Commit 2d7893d0 authored by Chris Allegretta's avatar Chris Allegretta
Browse files

Added multi buffer (load on insert) code. This wont intoduce any bugs ;-)

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@722 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
parent 240998b2
Showing with 1938 additions and 1073 deletions
+1938 -1073
...@@ -51,6 +51,14 @@ Cvs code - ...@@ -51,6 +51,14 @@ Cvs code -
- New macro TOGGLE which just toggles, no more silly checking - New macro TOGGLE which just toggles, no more silly checking
ISSET and then using SET or UNSET when we want a simple toggle ISSET and then using SET or UNSET when we want a simple toggle
for a flag. for a flag.
- Added multiple buffer capability (God help us). New configure
option --enable-loadoninsert (-L), changes to do_insertfile(),
do_insertfile_void(), toggle_init(), do_gotoline(), edit_update(),
and write_file(), new functions add_open_file(),
open_file_change_name(), load_open_file(), open_file_dup_search(),
open_file_dup_fix(), open_prevfile(), open_nextfile(),
close_open_file(), get_full_path(), die_save_file(), etc.
(David Lawrence Ramsey).
- Makefile.am: - Makefile.am:
- Include ABOUT-NLS and the new THANKS files to the distributed list. - Include ABOUT-NLS and the new THANKS files to the distributed list.
- THANKS: - THANKS:
......
...@@ -57,24 +57,27 @@ POST_INSTALL = : ...@@ -57,24 +57,27 @@ POST_INSTALL = :
NORMAL_UNINSTALL = : NORMAL_UNINSTALL = :
PRE_UNINSTALL = : PRE_UNINSTALL = :
POST_UNINSTALL = : POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CATALOGS = @CATALOGS@ CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@ CATOBJEXT = @CATOBJEXT@
CC = @CC@ CC = @CC@
CURSES_LIB = @CURSES_LIB@ CURSES_LIB = @CURSES_LIB@
DATADIRNAME = @DATADIRNAME@ DATADIRNAME = @DATADIRNAME@
GENCAT = @GENCAT@ GENCAT = @GENCAT@
GLIBC21 = @GLIBC21@
GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_CONFIG = @GLIB_CONFIG@ GLIB_CONFIG = @GLIB_CONFIG@
GLIB_LIBS = @GLIB_LIBS@ GLIB_LIBS = @GLIB_LIBS@
GMOFILES = @GMOFILES@ GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@ GMSGFMT = @GMSGFMT@
GT_NO = @GT_NO@
GT_YES = @GT_YES@
INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
INSTOBJEXT = @INSTOBJEXT@ INSTOBJEXT = @INSTOBJEXT@
INTLDEPS = @INTLDEPS@ INTLBISON = @INTLBISON@
INTLLIBS = @INTLLIBS@ INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@ INTLOBJS = @INTLOBJS@
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
LIBICONV = @LIBICONV@
MKINSTALLDIRS = @MKINSTALLDIRS@ MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@ MSGFMT = @MSGFMT@
PACKAGE = @PACKAGE@ PACKAGE = @PACKAGE@
...@@ -84,7 +87,6 @@ RANLIB = @RANLIB@ ...@@ -84,7 +87,6 @@ RANLIB = @RANLIB@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@ USE_NLS = @USE_NLS@
VERSION = @VERSION@ VERSION = @VERSION@
l = @l@
bin_PROGRAMS = nano bin_PROGRAMS = nano
nano_SOURCES = color.c cut.c files.c global.c move.c nano.c nano.h proto.h rcfile.c search.c utils.c winio.c nano_SOURCES = color.c cut.c files.c global.c move.c nano.c nano.h proto.h rcfile.c search.c utils.c winio.c
......
...@@ -54,6 +54,9 @@ ...@@ -54,6 +54,9 @@
/* Define this to disable the mouse functions */ /* Define this to disable the mouse functions */
#undef DISABLE_MOUSE #undef DISABLE_MOUSE
/* Define this to load files upon inserting them, and allow switching between them; this is disabled if NANO_SMALL is defined */
#undef ENABLE_LOADONINSERT
/* Define this to use the .nanorc file */ /* Define this to use the .nanorc file */
#undef ENABLE_NANORC #undef ENABLE_NANORC
......
This diff is collapsed.
...@@ -31,9 +31,6 @@ ...@@ -31,9 +31,6 @@
/* Define to `long' if <sys/types.h> doesn't define. */ /* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t #undef off_t
/* Define if you need to in order for stat and other things to work. */
#undef _POSIX_SOURCE
/* Define as the return type of signal handlers (int or void). */ /* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE #undef RETSIGTYPE
...@@ -61,21 +58,6 @@ ...@@ -61,21 +58,6 @@
/* Define this if your curses lib has the _use_keypad flag */ /* Define this if your curses lib has the _use_keypad flag */
#undef HAVE_USEKEYPAD #undef HAVE_USEKEYPAD
/* Define this if you have NLS */
#undef ENABLE_NLS
/* Define this is you have the catgets command */
#undef HAVE_CATGETS
/* Define this is you have GNU gettext */
#undef HAVE_GETTEXT
/* Define this for HAVE_LC_MESSAGES */
#undef HAVE_LC_MESSAGES
/* Define this if you have the stpcpy function (cool) */
#undef HAVE_STPCPY
/* Define this to make the nano executable as small as possible */ /* Define this to make the nano executable as small as possible */
#undef NANO_SMALL #undef NANO_SMALL
...@@ -106,6 +88,9 @@ ...@@ -106,6 +88,9 @@
/* Define this to disable the mouse functions */ /* Define this to disable the mouse functions */
#undef DISABLE_MOUSE #undef DISABLE_MOUSE
/* Define this to load files upon inserting them, and allow switching between them; this is disabled if NANO_SMALL is defined */
#undef ENABLE_LOADONINSERT
/* Define this to use the .nanorc file */ /* Define this to use the .nanorc file */
#undef ENABLE_NANORC #undef ENABLE_NANORC
...@@ -127,15 +112,36 @@ ...@@ -127,15 +112,36 @@
/* Define if you have the dcgettext function. */ /* Define if you have the dcgettext function. */
#undef HAVE_DCGETTEXT #undef HAVE_DCGETTEXT
/* Define if you have the feof_unlocked function. */
#undef HAVE_FEOF_UNLOCKED
/* Define if you have the fgets_unlocked function. */
#undef HAVE_FGETS_UNLOCKED
/* Define if you have the getcwd function. */ /* Define if you have the getcwd function. */
#undef HAVE_GETCWD #undef HAVE_GETCWD
/* Define if you have the getegid function. */
#undef HAVE_GETEGID
/* Define if you have the geteuid function. */
#undef HAVE_GETEUID
/* Define if you have the getgid function. */
#undef HAVE_GETGID
/* Define if you have the getopt_long function. */ /* Define if you have the getopt_long function. */
#undef HAVE_GETOPT_LONG #undef HAVE_GETOPT_LONG
/* Define if you have the getpagesize function. */ /* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE #undef HAVE_GETPAGESIZE
/* Define if you have the getuid function. */
#undef HAVE_GETUID
/* Define if you have the mempcpy function. */
#undef HAVE_MEMPCPY
/* Define if you have the munmap function. */ /* Define if you have the munmap function. */
#undef HAVE_MUNMAP #undef HAVE_MUNMAP
...@@ -163,6 +169,12 @@ ...@@ -163,6 +169,12 @@
/* Define if you have the strdup function. */ /* Define if you have the strdup function. */
#undef HAVE_STRDUP #undef HAVE_STRDUP
/* Define if you have the strtoul function. */
#undef HAVE_STRTOUL
/* Define if you have the tsearch function. */
#undef HAVE_TSEARCH
/* Define if you have the vsnprintf function. */ /* Define if you have the vsnprintf function. */
#undef HAVE_VSNPRINTF #undef HAVE_VSNPRINTF
...@@ -196,6 +208,12 @@ ...@@ -196,6 +208,12 @@
/* Define if you have the <regex.h> header file. */ /* Define if you have the <regex.h> header file. */
#undef HAVE_REGEX_H #undef HAVE_REGEX_H
/* Define if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <string.h> header file. */ /* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H #undef HAVE_STRING_H
...@@ -211,12 +229,28 @@ ...@@ -211,12 +229,28 @@
/* Define if you have the <unistd.h> header file. */ /* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H #undef HAVE_UNISTD_H
/* Define if you have the i library (-li). */
#undef HAVE_LIBI
/* Name of package */ /* Name of package */
#undef PACKAGE #undef PACKAGE
/* Version number of package */ /* Version number of package */
#undef VERSION #undef VERSION
/* Define if you have the iconv() function. */
#undef HAVE_ICONV
/* Define as const if the declaration of iconv() needs const. */
#undef ICONV_CONST
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#undef HAVE_LANGINFO_CODESET
/* Define if your <locale.h> file defines LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define to 1 if translation of program messages to the user's native language
is requested. */
#undef ENABLE_NLS
/* Define if the GNU gettext() function is already present or preinstalled. */
#undef HAVE_GETTEXT
This diff is collapsed.
...@@ -33,6 +33,12 @@ AC_ARG_ENABLE(extra, ...@@ -33,6 +33,12 @@ AC_ARG_ENABLE(extra,
AC_DEFINE(NANO_EXTRA) extra_support=yes AC_DEFINE(NANO_EXTRA) extra_support=yes
fi]) fi])
AC_ARG_ENABLE(loadoninsert,
[ --enable-loadoninsert Enable use of file loading on insertion, and switching between loaded files; this is disabled if --enable-tiny is used],
[if test x$enableval = xyes && test x$tiny_support != xyes; then
AC_DEFINE(ENABLE_LOADONINSERT) loadoninsert_support=yes
fi])
AC_ARG_ENABLE(nanorc, AC_ARG_ENABLE(nanorc,
[ --enable-nanorc Enable use of .nanorc file], [ --enable-nanorc Enable use of .nanorc file],
[if test x$enableval = xyes; then [if test x$enableval = xyes; then
......
...@@ -47,6 +47,16 @@ ...@@ -47,6 +47,16 @@
void load_file(void) void load_file(void)
{ {
current = fileage; current = fileage;
#ifdef ENABLE_LOADONINSERT
/* add a new entry to the open_files structure, and check for
duplicate entries; if a duplicate entry was found, reload the
currently open file (it may have been changed during duplicate
handling) */
if (add_open_file(0, 1) == 2)
load_open_file();
#endif
wmove(edit, current_y, current_x); wmove(edit, current_y, current_x);
} }
...@@ -253,7 +263,7 @@ int open_file(char *filename, int insert, int quiet) ...@@ -253,7 +263,7 @@ int open_file(char *filename, int insert, int quiet)
return 1; return 1;
} }
int do_insertfile(void) int do_insertfile(int loading_file)
{ {
int i; int i;
char *realname = NULL; char *realname = NULL;
...@@ -270,7 +280,7 @@ int do_insertfile(void) ...@@ -270,7 +280,7 @@ int do_insertfile(void)
if (i != -1) { if (i != -1) {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "filename is %s", answer); fprintf(stderr, _("filename is %s"), answer);
#endif #endif
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
...@@ -294,19 +304,57 @@ int do_insertfile(void) ...@@ -294,19 +304,57 @@ int do_insertfile(void)
if (tmp != NULL) if (tmp != NULL)
realname = mallocstrcpy(realname, tmp); realname = mallocstrcpy(realname, tmp);
else else
return do_insertfile(); return do_insertfile(loading_file);
}
#endif
#ifdef ENABLE_LOADONINSERT
if (loading_file) {
/* update the current entry in the open_files structure; we
don't need to check for duplicate entries (the conditions
that could create them are taken care of elsewhere) */
add_open_file(1, 0);
free_filestruct(current);
new_file();
UNSET(MODIFIED);
} }
#endif #endif
i = open_file(realname, 1, 0); i = open_file(realname, 1, 0);
#ifdef ENABLE_LOADONINSERT
if (loading_file)
filename = mallocstrcpy(filename, realname);
#endif
free(realname); free(realname);
dump_buffer(fileage); dump_buffer(fileage);
set_modified();
#ifdef ENABLE_LOADONINSERT
if (loading_file)
load_file();
else
#endif
set_modified();
/* Here we want to rebuild the edit window */ /* Here we want to rebuild the edit window */
fix_editbot(); fix_editbot();
#ifdef ENABLE_LOADONINSERT
/* If we've loaded another file, update the titlebar's contents */
if (loading_file) {
clearok(topwin, FALSE);
titlebar(NULL);
/* And re-init the shortcut list */
shortcut_init(0);
}
#endif
/* If we've gone off the bottom, recenter; otherwise, just redraw */ /* If we've gone off the bottom, recenter; otherwise, just redraw */
if (current->lineno > editbot->lineno) if (current->lineno > editbot->lineno)
edit_update(current, CENTER); edit_update(current, CENTER);
...@@ -324,6 +372,479 @@ int do_insertfile(void) ...@@ -324,6 +372,479 @@ int do_insertfile(void)
} }
} }
int do_insertfile_void(void)
{
int result = 0;
#ifdef ENABLE_LOADONINSERT
result = do_insertfile(ISSET(LOADONINSERT));
#else
result = do_insertfile(0);
#endif
display_main_list();
return result;
}
#ifdef ENABLE_LOADONINSERT
/*
* Add/update an entry to the open_files filestruct. If update is
* zero, a new entry is created; otherwise, the current entry is updated.
* If dup_fix is zero, checking for and handling duplicate entries is not
* done; otherwise, it is. Return 0 on success, 1 on error, or 2 on
* finding a duplicate entry.
*/
int add_open_file(int update, int dup_fix)
{
filestruct *tmp;
if (!current || !filename)
return 1;
/* first, if duplicate checking is allowed, do it */
if (dup_fix) {
/* if duplicates were found and handled, we're done */
if (open_file_dup_fix(update))
return 2;
}
/* if no entries, make the first one */
if (!open_files) {
open_files = make_new_node(NULL);
/* if open_files->file is NULL at the nrealloc() below, we get a
segfault */
open_files->file = open_files;
}
else if (!update) {
/* otherwise, if we're not updating, make a new entry for
open_files and splice it in after the current one */
#ifdef DEBUG
fprintf(stderr, _("filename is %s"), open_files->data);
#endif
tmp = make_new_node(NULL);
splice_node(open_files, tmp, open_files->next);
open_files = open_files->next;
/* if open_files->file is NULL at the nrealloc() below, we get a
segfault */
open_files->file = open_files;
}
/* save current filename */
open_files->data = mallocstrcpy(open_files->data, filename);
/* save the full path location */
open_files->file_path = get_full_path(open_files->data);
/* save current total number of lines */
open_files->file_totlines = totlines;
/* save current total size */
open_files->file_totsize = totsize;
/* save current x-coordinate position */
open_files->file_current_x = current_x;
/* save current y-coordinate position */
open_files->file_current_y = current_y;
/* save current place we want */
open_files->file_placewewant = placewewant;
/* save current line number */
open_files->lineno = current->lineno;
/* save current filestruct */
open_files->file = nrealloc(open_files->file, sizeof(filestruct));
while (current->prev)
current = current->prev;
open_files->file = copy_filestruct(current);
do_gotoline(open_files->lineno, 1);
placewewant = open_files->file_placewewant;
update_line(current, current_x);
/* save current modification status */
open_files->file_modified = ISSET(MODIFIED);
#ifdef DEBUG
fprintf(stderr, _("filename is %s"), open_files->data);
#endif
return 0;
}
/*
* Update only the filename and full path stored in the current entry.
* Return 0 on success or 1 on error.
*/
int open_file_change_name(void)
{
if (!open_files || !filename)
return 1;
/* save current filename */
open_files->data = mallocstrcpy(open_files->data, filename);
/* save the full path location */
open_files->file_path = get_full_path(open_files->data);
return 0;
}
/*
* Read the current entry in the open_files structure and set up the
* currently open file using that entry's information. Return 0 on
* success or 1 on error.
*/
int load_open_file(void)
{
if (!open_files)
return 1;
/* set up the filename, the file buffer, the total number of lines in
the file, and the total file size */
filename = mallocstrcpy(filename, open_files->data);
fileage = copy_filestruct(open_files->file);
current = fileage;
totlines = open_files->file_totlines;
totsize = open_files->file_totsize;
/* since do_gotoline() resets the x-coordinate but not the
y-coordinate, set all coordinates up this way */
current_y = open_files->file_current_y;
do_gotoline(open_files->lineno, 1);
current_x = open_files->file_current_x;
placewewant = open_files->file_placewewant;
update_line(current, current_x);
/* set up modification status and update the titlebar */
if (open_files->file_modified)
SET(MODIFIED);
else
UNSET(MODIFIED);
clearok(topwin, FALSE);
titlebar(NULL);
/* if we're constantly displaying the cursor position, update it */
if (ISSET(CONSTUPDATE))
do_cursorpos();
/* now we're done */
return 0;
}
/*
* Search the open_files structure for an entry with the same value for
* the file_path member as the current entry (i. e. a duplicate entry).
* If one is found, return a pointer to it; otherwise, return NULL.
*
* Note: This should only be called inside open_file_dup_fix().
*/
filestruct *open_file_dup_search(void)
{
filestruct *tmp;
char *path;
if (!open_files || !filename)
return NULL;
tmp = open_files;
path = get_full_path(filename);
/* if there's only one entry, handle it */
if (!tmp->prev && !tmp->next) {
if (!strcmp(tmp->file_path, path))
return tmp;
}
/* otherwise, go to the beginning */
while (tmp->prev)
tmp = tmp->prev;
/* and search the entries one by one */
while (tmp) {
if (!strcmp(tmp->file_path, path)) {
/* if it's not the current entry, we've found a duplicate */
if (tmp != open_files)
return tmp;
}
/* go to the next entry */
tmp = tmp->next;
}
return NULL;
}
/*
* Search for duplicate entries in the open_files structure using
* open_file_dup_search(), and, if one is found, handle it properly.
* Return 0 if no duplicates were found, and 1 otherwise.
*/
int open_file_dup_fix(int update)
{
filestruct *tmp = open_file_dup_search();
if (!tmp)
return 0;
/* if there's only one entry, handle it */
if (!tmp->prev && !tmp->next)
return 1;
/* otherwise, if we're not updating, the user's trying to load a
duplicate; switch to the original instead */
if (!update) {
open_files = tmp;
return 1;
}
/* if we are updating, the filename's been changed via a save; it's
thus more recent than the original, so remove the original */
else {
unlink_node(tmp);
free_filestruct(tmp->file);
free(tmp->file_path);
delete_node(tmp);
}
return 0;
}
/*
* Open the previous entry in the open_files structure. If closing_file
* is zero, update the current entry before switching from it.
* Otherwise, we are about to close that entry, so don't bother doing so.
* Return 0 on success and 1 on error.
*/
int open_prevfile(int closing_file)
{
if (!open_files)
return 1;
/* if we're not about to close the current entry, update it before
doing anything; since we're only switching, we don't need to check
for duplicate entries */
if (!closing_file)
add_open_file(1, 0);
if (!open_files->prev && !open_files->next) {
/* only one file open */
if (!closing_file)
statusbar(_("No more open files"));
return 1;
}
if (open_files->prev) {
open_files = open_files->prev;
#ifdef DEBUG
fprintf(stderr, _("filename is %s"), open_files->data);
#endif
}
else if (open_files->next) {
/* if we're at the beginning, wrap around to the end */
while (open_files->next)
open_files = open_files->next;
#ifdef DEBUG
fprintf(stderr, _("filename is %s"), open_files->data);
#endif
}
load_open_file();
#ifdef DEBUG
dump_buffer(current);
#endif
return 0;
}
/*
* Open the next entry in the open_files structure. If closing_file is
* zero, update the current entry before switching from it. Otherwise, we
* are about to close that entry, so don't bother doing so. Return 0 on
* success and 1 on error.
*/
int open_nextfile(int closing_file)
{
if (!open_files)
return 1;
/* if we're not about to close the current entry, update it before
doing anything; since we're only switching, we don't need to check
for duplicate entries */
if (!closing_file)
add_open_file(1, 0);
if (!open_files->prev && !open_files->next) {
/* only one file open */
if (!closing_file)
statusbar(_("No more open files"));
return 1;
}
if (open_files->next) {
open_files = open_files->next;
#ifdef DEBUG
fprintf(stderr, _("filename is %s"), open_files->data);
#endif
}
else if (open_files->prev) {
/* if we're at the end, wrap around to the beginning */
while (open_files->prev) {
open_files = open_files->prev;
#ifdef DEBUG
fprintf(stderr, _("filename is %s"), open_files->data);
#endif
}
}
load_open_file();
#ifdef DEBUG
dump_buffer(current);
#endif
return 0;
}
/*
* Delete an entry from the open_files filestruct. After deletion of an
* entry, the previous or next entry is opened, whichever is found first.
* Return 0 on success or 1 on error.
*/
int close_open_file(void)
{
filestruct *tmp;
if (!open_files)
return 1;
tmp = open_files;
if (open_prevfile(1)) {
if (open_nextfile(1))
return 1;
}
unlink_node(tmp);
free_filestruct(tmp->file);
free(tmp->file_path);
delete_node(tmp);
shortcut_init(0);
display_main_list();
return 0;
}
/*
* When passed "[relative path][filename]" in origpath, return "[full
* path][filename]" on success, or NULL on error.
*/
char *get_full_path(const char *origpath)
{
char *newpath = NULL, *last_slash, *d_here, *d_there, *d_there_file;
int last_slash_index;
/* first, get the current directory */
#ifdef PATH_MAX
d_here = getcwd(NULL, PATH_MAX + 1);
#else
d_here = getcwd(NULL, 0);
#endif
if (d_here) {
align(&d_here);
/* get the filename (with path included) and save it in both
d_there and d_there_file */
d_there = charalloc(strlen(origpath) + 1);
d_there_file = charalloc(strlen(origpath) + 1);
strcpy(d_there, origpath);
strcpy(d_there_file, origpath);
/* search for the last slash in d_there */
last_slash = strrchr(d_there, '/');
/* if we didn't find one, copy d_here into d_there; all data is
then set up */
if (!last_slash) {
d_there = nrealloc(d_there, strlen(d_here) + 1);
strcpy(d_there, d_here);
}
else {
/* otherwise, remove all non-path elements from d_there */
last_slash_index = strlen(d_there) - strlen(last_slash);
null_at(d_there, last_slash_index);
/* and remove all non-file elements from d_there_file */
last_slash++;
d_there_file = nrealloc(d_there_file, strlen(last_slash) + 1);
strcpy(d_there_file, last_slash);
/* now go to the path specified in d_there */
if (chdir(d_there) != -1) {
/* get the full pathname, and save it back in d_there */
free(d_there);
#ifdef PATH_MAX
d_there = getcwd(NULL, PATH_MAX + 1);
#else
d_there = getcwd(NULL, 0);
#endif
align(&d_there);
}
/* finally, go back to where we were before, d_here (no error
checking is done on this chdir(), because we can do
nothing if it fails) */
chdir(d_here);
}
/* all data is set up; fill in newpath */
/* newpath = d_there + "/" + d_there_file */
newpath = charalloc(strlen(d_there) + strlen(d_there_file) + 2);
strcpy(newpath, d_there);
strcat(newpath, "/");
strcat(newpath, d_there_file);
/* finally, clean up */
free(d_there_file);
free(d_there);
free(d_here);
}
return newpath;
}
#endif
/* /*
* Write a file out. If tmp is nonzero, we set the umask to 0600, * Write a file out. If tmp is nonzero, we set the umask to 0600,
* we don't set the global variable filename to its name, and don't * we don't set the global variable filename to its name, and don't
...@@ -637,7 +1158,29 @@ int do_writeout(char *path, int exiting, int append) ...@@ -637,7 +1158,29 @@ int do_writeout(char *path, int exiting, int append)
} else } else
#endif #endif
i = write_file(answer, 0, append, 0); i = write_file(answer, 0, append, 0);
#ifdef ENABLE_LOADONINSERT
/* if we're not about to exit, update the current entry in
the open_files structure */
if (!exiting) {
/* first, if the filename was changed during the save,
update the filename and full path stored in the
current entry, and then update the current entry,
checking for duplicate entries */
if (strcmp(open_files->data, filename)) {
open_file_change_name();
add_open_file(1, 1);
}
else {
/* otherwise, just update the current entry without
checking for duplicate entries */
add_open_file(1, 0);
}
}
#endif
display_main_list(); display_main_list();
return i; return i;
} else { } else {
......
...@@ -54,6 +54,10 @@ filestruct *editbot = NULL; /* Same for the bottom */ ...@@ -54,6 +54,10 @@ filestruct *editbot = NULL; /* Same for the bottom */
filestruct *filebot = NULL; /* Last node in the file struct */ filestruct *filebot = NULL; /* Last node in the file struct */
filestruct *cutbuffer = NULL; /* A place to store cut text */ filestruct *cutbuffer = NULL; /* A place to store cut text */
#ifdef ENABLE_LOADONINSERT
filestruct *open_files = NULL; /* The list of open files */
#endif
char *answer = NULL; /* Answer str to many questions */ char *answer = NULL; /* Answer str to many questions */
int totlines = 0; /* Total number of lines in the file */ int totlines = 0; /* Total number of lines in the file */
int totsize = 0; /* Total number of bytes in the file */ int totsize = 0; /* Total number of bytes in the file */
...@@ -126,11 +130,13 @@ void sc_init_one(shortcut * s, int key, char *desc, char *help, int alt, ...@@ -126,11 +130,13 @@ void sc_init_one(shortcut * s, int key, char *desc, char *help, int alt,
#ifndef NANO_SMALL #ifndef NANO_SMALL
/* Initialize the toggles in the same manner */ /* Initialize the toggles in the same manner */
void toggle_init_one(toggle * t, int val, char *desc, int flag) void toggle_init_one(toggle * t, int val, char *desc, int flag,
char override_ch)
{ {
t->val = val; t->val = val;
t->desc = desc; t->desc = desc;
t->flag = flag; t->flag = flag;
t->override_ch = override_ch;
} }
#endif #endif
...@@ -141,6 +147,11 @@ void toggle_init(void) ...@@ -141,6 +147,11 @@ void toggle_init(void)
*toggle_nohelp_msg, *toggle_picomode_msg, *toggle_mouse_msg, *toggle_nohelp_msg, *toggle_picomode_msg, *toggle_mouse_msg,
*toggle_cuttoend_msg, *toggle_wrap_msg, *toggle_case_msg, *toggle_cuttoend_msg, *toggle_wrap_msg, *toggle_case_msg,
*toggle_backwards_msg; *toggle_backwards_msg;
#ifdef ENABLE_LOADONINSERT
char *toggle_load_msg, *nano_openprev_msg, *nano_opennext_msg;
#endif
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
char *toggle_regexp_msg; char *toggle_regexp_msg;
#endif #endif
...@@ -159,29 +170,45 @@ void toggle_init(void) ...@@ -159,29 +170,45 @@ void toggle_init(void)
#endif #endif
toggle_wrap_msg = _("Auto wrap"); toggle_wrap_msg = _("Auto wrap");
#ifdef ENABLE_LOADONINSERT
toggle_load_msg = _("File loading on insertion");
nano_openprev_msg = _("Open previously loaded file");
nano_opennext_msg = _("Open next loaded file");
#endif
toggle_init_one(&toggles[0], TOGGLE_CONST_KEY, toggle_const_msg, toggle_init_one(&toggles[0], TOGGLE_CONST_KEY, toggle_const_msg,
CONSTUPDATE); CONSTUPDATE, 0);
toggle_init_one(&toggles[1], TOGGLE_AUTOINDENT_KEY, toggle_init_one(&toggles[1], TOGGLE_AUTOINDENT_KEY,
toggle_autoindent_msg, AUTOINDENT); toggle_autoindent_msg, AUTOINDENT, 0);
toggle_init_one(&toggles[2], TOGGLE_SUSPEND_KEY, toggle_suspend_msg, toggle_init_one(&toggles[2], TOGGLE_SUSPEND_KEY, toggle_suspend_msg,
SUSPEND); SUSPEND, 0);
toggle_init_one(&toggles[3], TOGGLE_NOHELP_KEY, toggle_nohelp_msg, toggle_init_one(&toggles[3], TOGGLE_NOHELP_KEY, toggle_nohelp_msg,
NO_HELP); NO_HELP, 0);
toggle_init_one(&toggles[4], TOGGLE_PICOMODE_KEY, toggle_picomode_msg, toggle_init_one(&toggles[4], TOGGLE_PICOMODE_KEY, toggle_picomode_msg,
PICO_MODE); PICO_MODE, 0);
toggle_init_one(&toggles[5], TOGGLE_WRAP_KEY, toggle_wrap_msg, toggle_init_one(&toggles[5], TOGGLE_WRAP_KEY, toggle_wrap_msg,
NO_WRAP); NO_WRAP, 0);
toggle_init_one(&toggles[6], TOGGLE_MOUSE_KEY, toggle_mouse_msg, toggle_init_one(&toggles[6], TOGGLE_MOUSE_KEY, toggle_mouse_msg,
USE_MOUSE); USE_MOUSE, 0);
toggle_init_one(&toggles[7], TOGGLE_CUTTOEND_KEY, toggle_cuttoend_msg, toggle_init_one(&toggles[7], TOGGLE_CUTTOEND_KEY, toggle_cuttoend_msg,
CUT_TO_END); CUT_TO_END, 0);
toggle_init_one(&toggles[8], TOGGLE_BACKWARDS_KEY, toggle_backwards_msg, toggle_init_one(&toggles[8], TOGGLE_BACKWARDS_KEY, toggle_backwards_msg,
REVERSE_SEARCH); REVERSE_SEARCH, 0);
toggle_init_one(&toggles[9], TOGGLE_CASE_KEY, toggle_case_msg, toggle_init_one(&toggles[9], TOGGLE_CASE_KEY, toggle_case_msg,
CASE_SENSITIVE); CASE_SENSITIVE, 0);
#ifdef ENABLE_LOADONINSERT
toggle_init_one(&toggles[10], TOGGLE_LOAD_KEY, toggle_load_msg,
LOADONINSERT, 0);
toggle_init_one(&toggles[11], NANO_OPENPREV_KEY, nano_openprev_msg,
0, '<');
toggle_init_one(&toggles[12], NANO_OPENNEXT_KEY, nano_opennext_msg,
0, '>');
#endif
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
toggle_init_one(&toggles[10], TOGGLE_REGEXP_KEY, toggle_regexp_msg, toggle_init_one(&toggles[TOGGLE_LEN - 1], TOGGLE_REGEXP_KEY,
USE_REGEXP); toggle_regexp_msg, USE_REGEXP, 0);
#endif #endif
#endif #endif
} }
...@@ -210,7 +237,13 @@ void shortcut_init(int unjustify) ...@@ -210,7 +237,13 @@ void shortcut_init(int unjustify)
nano_help_msg = _("Invoke the help menu"); nano_help_msg = _("Invoke the help menu");
nano_writeout_msg = _("Write the current file to disk"); nano_writeout_msg = _("Write the current file to disk");
#ifdef ENABLE_LOADONINSERT
nano_exit_msg = _("Close currently loaded file/Exit from nano");
#else
nano_exit_msg = _("Exit from nano"); nano_exit_msg = _("Exit from nano");
#endif
nano_goto_msg = _("Goto a specific line number"); nano_goto_msg = _("Goto a specific line number");
nano_justify_msg = _("Justify the current paragraph"); nano_justify_msg = _("Justify the current paragraph");
nano_unjustify_msg = _("Unjustify after a justify"); nano_unjustify_msg = _("Unjustify after a justify");
...@@ -251,7 +284,13 @@ void shortcut_init(int unjustify) ...@@ -251,7 +284,13 @@ void shortcut_init(int unjustify)
sc_init_one(&main_list[0], NANO_HELP_KEY, _("Get Help"), sc_init_one(&main_list[0], NANO_HELP_KEY, _("Get Help"),
nano_help_msg, 0, NANO_HELP_FKEY, 0, VIEW, do_help); nano_help_msg, 0, NANO_HELP_FKEY, 0, VIEW, do_help);
sc_init_one(&main_list[1], NANO_EXIT_KEY, _("Exit"), #ifdef ENABLE_LOADONINSERT
if (open_files != NULL && (open_files->prev || open_files->next))
sc_init_one(&main_list[1], NANO_EXIT_KEY, _("Close"),
nano_exit_msg, 0, NANO_EXIT_FKEY, 0, VIEW, do_exit);
else
#endif
sc_init_one(&main_list[1], NANO_EXIT_KEY, _("Exit"),
nano_exit_msg, 0, NANO_EXIT_FKEY, 0, VIEW, do_exit); nano_exit_msg, 0, NANO_EXIT_FKEY, 0, VIEW, do_exit);
sc_init_one(&main_list[2], NANO_WRITEOUT_KEY, _("WriteOut"), sc_init_one(&main_list[2], NANO_WRITEOUT_KEY, _("WriteOut"),
...@@ -265,13 +304,13 @@ void shortcut_init(int unjustify) ...@@ -265,13 +304,13 @@ void shortcut_init(int unjustify)
else else
sc_init_one(&main_list[3], NANO_INSERTFILE_KEY, _("Read File"), sc_init_one(&main_list[3], NANO_INSERTFILE_KEY, _("Read File"),
nano_insert_msg, nano_insert_msg,
0, NANO_INSERTFILE_FKEY, 0, NOVIEW, do_insertfile); 0, NANO_INSERTFILE_FKEY, 0, NOVIEW, do_insertfile_void);
if (ISSET(PICO_MODE)) if (ISSET(PICO_MODE))
sc_init_one(&main_list[4], NANO_INSERTFILE_KEY, _("Read File"), sc_init_one(&main_list[4], NANO_INSERTFILE_KEY, _("Read File"),
nano_insert_msg, nano_insert_msg,
0, NANO_INSERTFILE_FKEY, 0, NOVIEW, do_insertfile); 0, NANO_INSERTFILE_FKEY, 0, NOVIEW, do_insertfile_void);
else else
sc_init_one(&main_list[4], NANO_REPLACE_KEY, _("Replace"), sc_init_one(&main_list[4], NANO_REPLACE_KEY, _("Replace"),
nano_replace_msg, nano_replace_msg,
......
...@@ -107,41 +107,76 @@ RETSIGTYPE finish(int sigage) ...@@ -107,41 +107,76 @@ RETSIGTYPE finish(int sigage)
void die(char *msg, ...) void die(char *msg, ...)
{ {
va_list ap; va_list ap;
char *name;
int i;
va_start(ap, msg); va_start(ap, msg);
vfprintf(stderr, msg, ap); vfprintf(stderr, msg, ap);
va_end(ap); va_end(ap);
/* Restore the old term settings */
tcsetattr(0, TCSANOW, &oldterm);
clear();
refresh();
resetty();
endwin();
fprintf(stderr, msg);
/* save the currently loaded file (if modified, its open_files entry
isn't up to date) */
die_save_file(filename);
#ifdef ENABLE_LOADONINSERT
/* then save all of the other loaded files, if any */
if (open_files) {
filestruct *tmp;
tmp = open_files;
while (open_files->prev)
open_files = open_files->prev;
while (open_files->next) {
/* if we already saved the file above (i. e. if it was the
currently loaded file), don't save it again */
if (tmp != open_files) {
fileage = open_files->file;
die_save_file(open_files->data);
}
open_files = open_files->next;
}
}
#endif
exit(1); /* We have a problem: exit w/ errorlevel(1) */
}
void die_save_file(char *die_filename)
{
char *name;
int i;
/* if we can't save we have REAL bad problems, /* if we can't save we have REAL bad problems,
* but we might as well TRY. */ * but we might as well TRY. */
if (filename[0] == '\0') { if (die_filename[0] == '\0') {
name = "nano.save"; name = "nano.save";
i = write_file(name, 1, 0, 0); i = write_file(name, 1, 0, 0);
} else { } else {
char *buf = charalloc(strlen(filename) + 6); char *buf = charalloc(strlen(die_filename) + 6);
strcpy(buf, filename); strcpy(buf, die_filename);
strcat(buf, ".save"); strcat(buf, ".save");
i = write_file(buf, 1, 0, 0); i = write_file(buf, 1, 0, 0);
name = buf; name = buf;
} }
/* Restore the old term settings */
tcsetattr(0, TCSANOW, &oldterm);
clear();
refresh();
resetty();
endwin();
fprintf(stderr, msg);
if (i != -1) if (i != -1)
fprintf(stderr, _("\nBuffer written to %s\n"), name); fprintf(stderr, _("\nBuffer written to %s\n"), name);
else else
fprintf(stderr, _("\nNo %s written (file exists?)\n"), name); fprintf(stderr, _("\nNo %s written (file exists?)\n"), name);
exit(1); /* We have a problem: exit w/ errorlevel(1) */
} }
/* Die with an error message that the screen was too small if, well, the /* Die with an error message that the screen was too small if, well, the
...@@ -225,7 +260,8 @@ void init_help_msg(void) ...@@ -225,7 +260,8 @@ void init_help_msg(void)
} }
#endif #endif
/* Make a copy of a node to a pointer (space will be malloc()ed) */ /* Make a copy of a node to a pointer (space will be malloc()ed). This
does NOT copy the data members used only by open_files. */
filestruct *copy_node(filestruct * src) filestruct *copy_node(filestruct * src)
{ {
filestruct *dst; filestruct *dst;
...@@ -252,6 +288,8 @@ void unlink_node(filestruct * fileptr) ...@@ -252,6 +288,8 @@ void unlink_node(filestruct * fileptr)
fileptr->next->prev = fileptr->prev; fileptr->next->prev = fileptr->prev;
} }
/* Delete a node from the struct. This does NOT delete the data members
used only by open_files. */
void delete_node(filestruct * fileptr) void delete_node(filestruct * fileptr)
{ {
if (fileptr == NULL) if (fileptr == NULL)
...@@ -262,7 +300,8 @@ void delete_node(filestruct * fileptr) ...@@ -262,7 +300,8 @@ void delete_node(filestruct * fileptr)
free(fileptr); free(fileptr);
} }
/* Okay, now let's duplicate a whole struct! */ /* Okay, now let's duplicate a whole struct! This does NOT duplicate the
data members used only by open_files. */
filestruct *copy_filestruct(filestruct * src) filestruct *copy_filestruct(filestruct * src)
{ {
filestruct *dst, *tmp, *head, *prev; filestruct *dst, *tmp, *head, *prev;
...@@ -286,6 +325,8 @@ filestruct *copy_filestruct(filestruct * src) ...@@ -286,6 +325,8 @@ filestruct *copy_filestruct(filestruct * src)
return head; return head;
} }
/* Frees a struct. This does NOT free the data members used only by
open_files. */
int free_filestruct(filestruct * src) int free_filestruct(filestruct * src)
{ {
filestruct *fileptr = src; filestruct *fileptr = src;
...@@ -360,6 +401,13 @@ void usage(void) ...@@ -360,6 +401,13 @@ void usage(void)
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
printf(_("Usage: nano [GNU long option] [option] +LINE <file>\n\n")); printf(_("Usage: nano [GNU long option] [option] +LINE <file>\n\n"));
printf(_("Option Long option Meaning\n")); printf(_("Option Long option Meaning\n"));
#ifdef ENABLE_LOADONINSERT
printf
(_
(" -L --loadoninsert Enable file loading on insertion\n"));
#endif
printf(_ printf(_
(" -T [num] --tabsize=[num] Set width of a tab to num\n")); (" -T [num] --tabsize=[num] Set width of a tab to num\n"));
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
...@@ -463,6 +511,9 @@ void version(void) ...@@ -463,6 +511,9 @@ void version(void)
#ifdef NANO_EXTRA #ifdef NANO_EXTRA
printf(" --enable-extra"); printf(" --enable-extra");
#endif #endif
#ifdef ENABLE_LOADONINSERT
printf(" --enable-loadoninsert");
#endif
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
printf(" --enable-nanorc"); printf(" --enable-nanorc");
#endif #endif
...@@ -503,6 +554,8 @@ void version(void) ...@@ -503,6 +554,8 @@ void version(void)
} }
/* Create a new node. This does NOT initialize the data members used
only by open_files. */
filestruct *make_new_node(filestruct * prevnode) filestruct *make_new_node(filestruct * prevnode)
{ {
filestruct *newnode; filestruct *newnode;
...@@ -519,7 +572,8 @@ filestruct *make_new_node(filestruct * prevnode) ...@@ -519,7 +572,8 @@ filestruct *make_new_node(filestruct * prevnode)
return newnode; return newnode;
} }
/* Splice a node into an existing filestruct */ /* Splice a node into an existing filestruct. This does NOT set the data
members used only by open_files. */
void splice_node(filestruct * begin, filestruct * newnode, void splice_node(filestruct * begin, filestruct * newnode,
filestruct * end) filestruct * end)
{ {
...@@ -1459,9 +1513,17 @@ int do_alt_speller(char *file_name) ...@@ -1459,9 +1513,17 @@ int do_alt_speller(char *file_name)
global_init(); global_init();
open_file(file_name, 0, 1); open_file(file_name, 0, 1);
do_gotoline(lineno_cur); do_gotoline(lineno_cur, 0);
set_modified(); set_modified();
#ifdef ENABLE_LOADONINSERT
/* if we have multiple files open, the spell-checked (current) file
is now stored after the un-spell-checked file in the open_files
structure, so go back to the un-spell-checked file and close it */
open_prevfile(0);
close_open_file();
#endif
return TRUE; return TRUE;
} }
#endif #endif
...@@ -1508,8 +1570,18 @@ int do_exit(void) ...@@ -1508,8 +1570,18 @@ int do_exit(void)
{ {
int i; int i;
if (!ISSET(MODIFIED)) if (!ISSET(MODIFIED)) {
finish(0);
#ifdef ENABLE_LOADONINSERT
if (!close_open_file()) {
display_main_list();
return 1;
}
else
#endif
finish(0);
}
if (ISSET(TEMP_OPT)) { if (ISSET(TEMP_OPT)) {
i = 1; i = 1;
...@@ -1524,11 +1596,30 @@ int do_exit(void) ...@@ -1524,11 +1596,30 @@ int do_exit(void)
#endif #endif
if (i == 1) { if (i == 1) {
if (do_writeout(filename, 1, 0) > 0) if (do_writeout(filename, 1, 0) > 0) {
#ifdef ENABLE_LOADONINSERT
if (!close_open_file()) {
display_main_list();
return 1;
}
else
#endif
finish(0);
}
} else if (i == 0) {
#ifdef ENABLE_LOADONINSERT
if (!close_open_file()) {
display_main_list();
return 1;
}
else
#endif
finish(0); finish(0);
} else if (i == 0) } else
finish(0);
else
statusbar(_("Cancelled")); statusbar(_("Cancelled"));
display_main_list(); display_main_list();
...@@ -2139,12 +2230,21 @@ void help_init(void) ...@@ -2139,12 +2230,21 @@ void help_init(void)
/* And the toggles... */ /* And the toggles... */
for (i = 0; i <= TOGGLE_LEN - 1; i++) { for (i = 0; i <= TOGGLE_LEN - 1; i++) {
sofar = snprintf(buf, BUFSIZ, if (toggles[i].override_ch != 0)
"M-%c ", toggles[i].val - 32); sofar = snprintf(buf, BUFSIZ,
"M-%c ", toggles[i].override_ch);
else
sofar = snprintf(buf, BUFSIZ,
"M-%c ", toggles[i].val - 32);
if (toggles[i].desc != NULL) if (toggles[i].desc != NULL) {
snprintf(&buf[sofar], BUFSIZ - sofar, _("%s enable/disable"), if (toggles[i].flag != 0)
toggles[i].desc); snprintf(&buf[sofar], BUFSIZ - sofar, _("%s enable/disable"),
toggles[i].desc);
else
snprintf(&buf[sofar], BUFSIZ - sofar, _("%s"),
toggles[i].desc);
}
strcat(help_text, buf); strcat(help_text, buf);
strcat(help_text, "\n"); strcat(help_text, "\n");
...@@ -2183,21 +2283,43 @@ void do_toggle(int which) ...@@ -2183,21 +2283,43 @@ void do_toggle(int which)
edit_refresh(); edit_refresh();
display_main_list(); display_main_list();
break; break;
#ifdef ENABLE_LOADONINSERT
case NANO_OPENPREV_KEY:
open_prevfile(0);
break;
case NANO_OPENNEXT_KEY:
open_nextfile(0);
break;
#endif
} }
if (!ISSET(toggles[which].flag)) { #ifdef ENABLE_LOADONINSERT
if (toggles[which].val == TOGGLE_NOHELP_KEY || /* NANO_OPENPREV_KEY and NANO_OPENNEXT_KEY aren't really toggles, so
toggles[which].val == TOGGLE_WRAP_KEY) don't display anything on the statusbar if they're pressed */
statusbar("%s %s", toggles[which].desc, enabled); if (toggles[which].val != NANO_OPENPREV_KEY &&
else toggles[which].val != NANO_OPENNEXT_KEY) {
statusbar("%s %s", toggles[which].desc, disabled); #endif
} else {
if (toggles[which].val == TOGGLE_NOHELP_KEY || if (!ISSET(toggles[which].flag)) {
toggles[which].val == TOGGLE_WRAP_KEY) if (toggles[which].val == TOGGLE_NOHELP_KEY ||
statusbar("%s %s", toggles[which].desc, disabled); toggles[which].val == TOGGLE_WRAP_KEY)
else statusbar("%s %s", toggles[which].desc, enabled);
statusbar("%s %s", toggles[which].desc, enabled); else
statusbar("%s %s", toggles[which].desc, disabled);
} else {
if (toggles[which].val == TOGGLE_NOHELP_KEY ||
toggles[which].val == TOGGLE_WRAP_KEY)
statusbar("%s %s", toggles[which].desc, disabled);
else
statusbar("%s %s", toggles[which].desc, enabled);
}
#ifdef ENABLE_LOADONINSERT
} }
#endif
SET(DISABLE_CURPOS); SET(DISABLE_CURPOS);
#endif #endif
...@@ -2279,6 +2401,11 @@ int main(int argc, char *argv[]) ...@@ -2279,6 +2401,11 @@ int main(int argc, char *argv[])
{"pico", 0, 0, 'p'}, {"pico", 0, 0, 'p'},
{"nofollow", 0, 0, 'l'}, {"nofollow", 0, 0, 'l'},
{"tabsize", 1, 0, 'T'}, {"tabsize", 1, 0, 'T'},
#ifdef ENABLE_LOADONINSERT
{"loadoninsert", 0, 0, 'L'},
#endif
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
#endif #endif
...@@ -2299,14 +2426,21 @@ int main(int argc, char *argv[]) ...@@ -2299,14 +2426,21 @@ int main(int argc, char *argv[])
#endif /* ENABLE_NANORC */ #endif /* ENABLE_NANORC */
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
while ((optchr = getopt_long(argc, argv, "?T:RVbcefghijklmpr:s:tvwxz", while ((optchr = getopt_long(argc, argv, "h?LT:RVbcefgijklmpr:s:tvwxz",
long_options, &option_index)) != EOF) { long_options, &option_index)) != EOF) {
#else #else
while ((optchr = while ((optchr =
getopt(argc, argv, "h?T:RVbcefgijklmpr:s:tvwxz")) != EOF) { getopt(argc, argv, "h?LT:RVbcefgijklmpr:s:tvwxz")) != EOF) {
#endif #endif
switch (optchr) { switch (optchr) {
#ifdef ENABLE_LOADONINSERT
case 'L':
SET(LOADONINSERT);
break;
#endif
case 'T': case 'T':
tabsize = atoi(optarg); tabsize = atoi(optarg);
if (tabsize <= 0) { if (tabsize <= 0) {
...@@ -2483,7 +2617,7 @@ int main(int argc, char *argv[]) ...@@ -2483,7 +2617,7 @@ int main(int argc, char *argv[])
open_file(filename, 0, 0); open_file(filename, 0, 0);
if (startline > 0) if (startline > 0)
do_gotoline(startline); do_gotoline(startline, 0);
else else
edit_update(fileage, CENTER); edit_update(fileage, CENTER);
...@@ -2583,7 +2717,12 @@ int main(int argc, char *argv[]) ...@@ -2583,7 +2717,12 @@ int main(int argc, char *argv[])
break; break;
case 126: /* Hack, make insert key do something case 126: /* Hack, make insert key do something
useful, like insert file */ useful, like insert file */
do_insertfile(); #ifdef ENABLE_LOADONINSERT
do_insertfile(ISSET(LOADONINSERT));
#else
do_insertfile(0);
#endif
keyhandled = 1; keyhandled = 1;
break; break;
#ifdef DEBUG #ifdef DEBUG
......
...@@ -73,6 +73,18 @@ typedef struct filestruct { ...@@ -73,6 +73,18 @@ typedef struct filestruct {
char *data; char *data;
struct filestruct *next; /* Next node */ struct filestruct *next; /* Next node */
struct filestruct *prev; /* Previous node */ struct filestruct *prev; /* Previous node */
#ifdef ENABLE_LOADONINSERT
struct filestruct *file; /* Current file */
int file_current_x; /* Current file's x-coordinate position */
int file_current_y; /* Current file's y-coordinate position */
int file_modified; /* Current file's modification status */
char *file_path; /* Current file's full path location */
int file_placewewant; /* Current file's place we want */
int file_totlines; /* Current file's total number of lines */
int file_totsize; /* Current file's total size */
#endif
long lineno; /* The line number */ long lineno; /* The line number */
} filestruct; } filestruct;
...@@ -93,6 +105,8 @@ typedef struct toggle { ...@@ -93,6 +105,8 @@ typedef struct toggle {
e.g. "Pico Messages"; we'll append Enabled or e.g. "Pico Messages"; we'll append Enabled or
Disabled */ Disabled */
int flag; /* What flag actually gets toggled */ int flag; /* What flag actually gets toggled */
char override_ch; /* The character to display on the help screen,
if it isn't NULL */
} toggle; } toggle;
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
...@@ -125,6 +139,7 @@ typedef struct rcoption { ...@@ -125,6 +139,7 @@ typedef struct rcoption {
#define CUT_TO_END (1<<17) #define CUT_TO_END (1<<17)
#define DISABLE_CURPOS (1<<18) #define DISABLE_CURPOS (1<<18)
#define REVERSE_SEARCH (1<<19) #define REVERSE_SEARCH (1<<19)
#define LOADONINSERT (1<<20)
/* Control key sequences, changing these would be very very bad */ /* Control key sequences, changing these would be very very bad */
...@@ -186,6 +201,8 @@ typedef struct rcoption { ...@@ -186,6 +201,8 @@ typedef struct rcoption {
#define NANO_ALT_X 'x' #define NANO_ALT_X 'x'
#define NANO_ALT_Y 'y' #define NANO_ALT_Y 'y'
#define NANO_ALT_Z 'z' #define NANO_ALT_Z 'z'
#define NANO_ALT_LCARAT ','
#define NANO_ALT_RCARAT '.'
/* Some semi-changeable keybindings; don't play with unless you're sure you /* Some semi-changeable keybindings; don't play with unless you're sure you
know what you're doing */ know what you're doing */
...@@ -241,6 +258,8 @@ know what you're doing */ ...@@ -241,6 +258,8 @@ know what you're doing */
#define NANO_FROMSEARCHTOGOTO_KEY NANO_CONTROL_T #define NANO_FROMSEARCHTOGOTO_KEY NANO_CONTROL_T
#define NANO_TOFILES_KEY NANO_CONTROL_T #define NANO_TOFILES_KEY NANO_CONTROL_T
#define NANO_APPEND_KEY NANO_ALT_A #define NANO_APPEND_KEY NANO_ALT_A
#define NANO_OPENPREV_KEY NANO_ALT_LCARAT
#define NANO_OPENNEXT_KEY NANO_ALT_RCARAT
#define TOGGLE_CONST_KEY NANO_ALT_C #define TOGGLE_CONST_KEY NANO_ALT_C
#define TOGGLE_AUTOINDENT_KEY NANO_ALT_I #define TOGGLE_AUTOINDENT_KEY NANO_ALT_I
...@@ -253,15 +272,28 @@ know what you're doing */ ...@@ -253,15 +272,28 @@ know what you're doing */
#define TOGGLE_WRAP_KEY NANO_ALT_W #define TOGGLE_WRAP_KEY NANO_ALT_W
#define TOGGLE_BACKWARDS_KEY NANO_ALT_B #define TOGGLE_BACKWARDS_KEY NANO_ALT_B
#define TOGGLE_CASE_KEY NANO_ALT_A #define TOGGLE_CASE_KEY NANO_ALT_A
#define TOGGLE_LOAD_KEY NANO_ALT_L
/* Toggle stuff, these static lengths need to go away RSN */ /* Toggle stuff, these static lengths need to go away RSN */
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
#ifdef ENABLE_LOADONINSERT
#define TOGGLE_LEN 14
#else
#define TOGGLE_LEN 11 #define TOGGLE_LEN 11
#endif
#define WHEREIS_LIST_LEN 8 #define WHEREIS_LIST_LEN 8
#define REPLACE_LIST_LEN 8 #define REPLACE_LIST_LEN 8
#else #else
#ifdef ENABLE_LOADONINSERT
#define TOGGLE_LEN 13
#else
#define TOGGLE_LEN 10 #define TOGGLE_LEN 10
#endif
#define WHEREIS_LIST_LEN 7 #define WHEREIS_LIST_LEN 7
#define REPLACE_LIST_LEN 7 #define REPLACE_LIST_LEN 7
#endif #endif
...@@ -286,6 +318,7 @@ know what you're doing */ ...@@ -286,6 +318,7 @@ know what you're doing */
#define VIEW 1 #define VIEW 1
#define NOVIEW 0 #define NOVIEW 0
#define NONE 3
#define TOP 2 #define TOP 2
#define CENTER 1 #define CENTER 1
#define BOTTOM 0 #define BOTTOM 0
......
...@@ -41,3 +41,6 @@ ...@@ -41,3 +41,6 @@
# Allow nano to be suepended with ^Z # Allow nano to be suepended with ^Z
# set suspend # set suspend
# Load files upon inserting them, and allow switching between them
# set loadoninsert
...@@ -50,6 +50,11 @@ extern char *alt_speller; ...@@ -50,6 +50,11 @@ extern char *alt_speller;
extern struct stat fileinfo; extern struct stat fileinfo;
extern filestruct *current, *fileage, *edittop, *editbot, *filebot; extern filestruct *current, *fileage, *edittop, *editbot, *filebot;
extern filestruct *cutbuffer, *mark_beginbuf; extern filestruct *cutbuffer, *mark_beginbuf;
#ifdef ENABLE_LOADONINSERT
extern filestruct *open_files;
#endif
extern shortcut *shortcut_list; extern shortcut *shortcut_list;
extern shortcut main_list[MAIN_LIST_LEN], whereis_list[WHEREIS_LIST_LEN]; extern shortcut main_list[MAIN_LIST_LEN], whereis_list[WHEREIS_LIST_LEN];
extern shortcut replace_list[REPLACE_LIST_LEN], goto_list[GOTO_LIST_LEN]; extern shortcut replace_list[REPLACE_LIST_LEN], goto_list[GOTO_LIST_LEN];
...@@ -89,8 +94,14 @@ int do_uncut_text(void); ...@@ -89,8 +94,14 @@ int do_uncut_text(void);
int no_help(void); int no_help(void);
int renumber_all(void); int renumber_all(void);
int open_file(char *filename, int insert, int quiet); int open_file(char *filename, int insert, int quiet);
int do_insertfile(int loading_file);
#ifdef ENABLE_LOADONINSERT
int add_open_file(int update, int dup_fix);
#endif
int do_writeout(char *path, int exiting, int append); int do_writeout(char *path, int exiting, int append);
int do_gotoline(long defline); int do_gotoline(long line, int save_pos);
int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx, int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
int wholewords, int *i); int wholewords, int *i);
/* Now in move.c */ /* Now in move.c */
...@@ -110,7 +121,7 @@ void check_wrap(filestruct * inptr, char ch); ...@@ -110,7 +121,7 @@ void check_wrap(filestruct * inptr, char ch);
void dump_buffer(filestruct * inptr); void dump_buffer(filestruct * inptr);
void align(char **strp); void align(char **strp);
void edit_refresh(void), edit_refresh_clearok(void); void edit_refresh(void), edit_refresh_clearok(void);
void edit_update(filestruct * fileptr, int topmidbot); void edit_update(filestruct * fileptr, int topmidbotnone);
void update_cursor(void); void update_cursor(void);
void delete_node(filestruct * fileptr); void delete_node(filestruct * fileptr);
void set_modified(void); void set_modified(void);
...@@ -136,6 +147,7 @@ void do_early_abort(void); ...@@ -136,6 +147,7 @@ void do_early_abort(void);
void *nmalloc(size_t howmuch); void *nmalloc(size_t howmuch);
void *nrealloc(void *ptr, size_t howmuch); void *nrealloc(void *ptr, size_t howmuch);
void die(char *msg, ...); void die(char *msg, ...);
void die_save_file(char *die_filename);
void new_file(void); void new_file(void);
void new_magicline(void); void new_magicline(void);
void splice_node(filestruct *begin, filestruct *newnode, filestruct *end); void splice_node(filestruct *begin, filestruct *newnode, filestruct *end);
...@@ -150,6 +162,7 @@ void nano_disabled_msg(void); ...@@ -150,6 +162,7 @@ void nano_disabled_msg(void);
void window_init(void); void window_init(void);
void do_mouse(void); void do_mouse(void);
void print_view_warning(void); void print_view_warning(void);
void unlink_node(filestruct * fileptr);
void cut_marked_segment(filestruct * top, int top_x, filestruct * bot, void cut_marked_segment(filestruct * top, int top_x, filestruct * bot,
int bot_x, int destructive); int bot_x, int destructive);
...@@ -163,7 +176,13 @@ void do_credits(void); ...@@ -163,7 +176,13 @@ void do_credits(void);
int do_writeout_void(void), do_exit(void), do_gotoline_void(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); int do_insertfile_void(void), do_search(void);
#ifdef ENABLE_LOADONINSERT
int load_open_file(void), close_open_file(void);
#endif
int page_up(void), page_down(void);
int do_cursorpos(void), do_spell(void); int do_cursorpos(void), do_spell(void);
int do_up(void), do_down (void), do_right(void), do_left (void); int do_up(void), do_down (void), do_right(void), do_left (void);
int do_home(void), do_end(void), total_refresh(void), do_mark(void); int do_home(void), do_end(void), total_refresh(void), do_mark(void);
...@@ -172,8 +191,17 @@ int do_first_line(void), do_last_line(void); ...@@ -172,8 +191,17 @@ int do_first_line(void), do_last_line(void);
int do_replace(void), do_help(void), do_enter_void(void); int do_replace(void), do_help(void), do_enter_void(void);
int keypad_on(WINDOW * win, int newval); int keypad_on(WINDOW * win, int newval);
#ifdef ENABLE_LOADONINSERT
int open_file_dup_fix(int update);
int open_prevfile(int closing_file), open_nextfile(int closing_file);
#endif
char *charalloc (size_t howmuch); char *charalloc (size_t howmuch);
#ifdef ENABLE_LOADONINSERT
char *get_full_path(const char *origpath);
#endif
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
char *do_browser(char *path); char *do_browser(char *path);
struct stat filestat(const char *path); struct stat filestat(const char *path);
...@@ -195,3 +223,7 @@ filestruct *copy_filestruct(filestruct * src); ...@@ -195,3 +223,7 @@ filestruct *copy_filestruct(filestruct * src);
filestruct *make_new_node(filestruct * prevnode); filestruct *make_new_node(filestruct * prevnode);
filestruct *findnextstr(int quiet, filestruct * begin, filestruct *findnextstr(int quiet, filestruct * begin,
int beginx, char *needle); int beginx, char *needle);
#ifdef ENABLE_LOADONINSERT
filestruct *open_file_dup_search(void);
#endif
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define _(string) (string) #define _(string) (string)
#endif #endif
#define NUM_RCOPTS 14 #define NUM_RCOPTS 15
/* Static stuff for the nanorc file */ /* Static stuff for the nanorc file */
rcoption rcopts[NUM_RCOPTS] = rcoption rcopts[NUM_RCOPTS] =
{ {
...@@ -60,7 +60,8 @@ rcoption rcopts[NUM_RCOPTS] = ...@@ -60,7 +60,8 @@ rcoption rcopts[NUM_RCOPTS] =
{"view", VIEW_MODE}, {"view", VIEW_MODE},
{"nowrap", NO_WRAP}, {"nowrap", NO_WRAP},
{"nohelp", NO_HELP}, {"nohelp", NO_HELP},
{"suspend", SUSPEND}}; {"suspend", SUSPEND},
{"loadoninsert", LOADONINSERT}};
/* We have an error in some part of the rcfile; put it on stderr and /* We have an error in some part of the rcfile; put it on stderr and
make the user hit return to continue starting up nano */ make the user hit return to continue starting up nano */
......
...@@ -743,7 +743,7 @@ void goto_abort(void) ...@@ -743,7 +743,7 @@ void goto_abort(void)
display_main_list(); display_main_list();
} }
int do_gotoline(long line) int do_gotoline(long line, int save_pos)
{ {
long i = 1; long i = 1;
...@@ -772,7 +772,13 @@ int do_gotoline(long line) ...@@ -772,7 +772,13 @@ int do_gotoline(long line)
current = current->next; current = current->next;
current_x = 0; current_x = 0;
edit_update(current, CENTER);
/* if save_pos is non-zero, don't change the cursor position when
updating the edit window */
if (save_pos)
edit_update(current, NONE);
else
edit_update(current, CENTER);
goto_abort(); goto_abort();
return 1; return 1;
...@@ -780,5 +786,5 @@ int do_gotoline(long line) ...@@ -780,5 +786,5 @@ int do_gotoline(long line)
int do_gotoline_void(void) int do_gotoline_void(void)
{ {
return do_gotoline(0); return do_gotoline(0, 0);
} }
...@@ -1079,7 +1079,7 @@ void edit_refresh_clearok(void) ...@@ -1079,7 +1079,7 @@ void edit_refresh_clearok(void)
* Nice generic routine to update the edit buffer, given a pointer to the * Nice generic routine to update the edit buffer, given a pointer to the
* file struct =) * file struct =)
*/ */
void edit_update(filestruct * fileptr, int topmidbot) void edit_update(filestruct * fileptr, int topmidbotnone)
{ {
int i = 0; int i = 0;
filestruct *temp; filestruct *temp;
...@@ -1088,8 +1088,11 @@ void edit_update(filestruct * fileptr, int topmidbot) ...@@ -1088,8 +1088,11 @@ void edit_update(filestruct * fileptr, int topmidbot)
return; return;
temp = fileptr; temp = fileptr;
if (topmidbot == 2); if (topmidbotnone == TOP);
else if (topmidbot == 0) else if (topmidbotnone == NONE)
for (i = 0; i <= current_y - 1 && temp->prev != NULL; i++)
temp = temp->prev;
else if (topmidbotnone == BOTTOM)
for (i = 0; i <= editwinrows - 1 && temp->prev != NULL; i++) for (i = 0; i <= editwinrows - 1 && temp->prev != NULL; i++)
temp = temp->prev; temp = temp->prev;
else else
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment