add DB's overhaul of the multibuffer code for efficiency, plus a few
tweaks and additions of mine git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2134 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
329d6a3259
commit
5b3dd0f423
14
ChangeLog
14
ChangeLog
|
@ -12,6 +12,20 @@ CVS code -
|
||||||
simplifies how they work, and to store such text in its own
|
simplifies how they work, and to store such text in its own
|
||||||
buffer rather than the cutbuffer. Changes to backup_lines(),
|
buffer rather than the cutbuffer. Changes to backup_lines(),
|
||||||
do_justify(), etc. (DLR)
|
do_justify(), etc. (DLR)
|
||||||
|
- Overhaul the multibuffer routines to increase efficiency, most
|
||||||
|
importantly making them use a doubly linked list for the open
|
||||||
|
files so that switching between them is no longer O(N), and
|
||||||
|
only including free_openfilestruct() when --enable-debug is
|
||||||
|
used. Also use some of the same efficiency tweaks when
|
||||||
|
dealing with filestruct nodes. New function
|
||||||
|
open_prevnext_file(); changes to make_new_opennode(),
|
||||||
|
splice_opennode(), unlink_opennode(), delete_opennode(),
|
||||||
|
free_openfilestruct(), add_open_file(), load_open_file(),
|
||||||
|
close_open_file(), shortcut_init(), die(), make_new_node(),
|
||||||
|
copy_node(), splice_node(), delete_node(), and
|
||||||
|
free_filestruct(); removal of open_prevfile() and
|
||||||
|
open_nextfile(). (David Benbennick, minor tweaks and additions
|
||||||
|
by DLR)
|
||||||
- cut.c:
|
- cut.c:
|
||||||
do_cut_text()
|
do_cut_text()
|
||||||
- If keep_cutbuffer is FALSE, only blow away the text in the
|
- If keep_cutbuffer is FALSE, only blow away the text in the
|
||||||
|
|
377
src/files.c
377
src/files.c
|
@ -694,17 +694,11 @@ void do_insertfile_void(void)
|
||||||
|
|
||||||
#ifdef ENABLE_MULTIBUFFER
|
#ifdef ENABLE_MULTIBUFFER
|
||||||
/* Create a new openfilestruct node. */
|
/* Create a new openfilestruct node. */
|
||||||
openfilestruct *make_new_opennode(openfilestruct *prevnode)
|
openfilestruct *make_new_opennode(void)
|
||||||
{
|
{
|
||||||
openfilestruct *newnode = (openfilestruct *)nmalloc(sizeof(openfilestruct));
|
openfilestruct *newnode =
|
||||||
|
(openfilestruct *)nmalloc(sizeof(openfilestruct));
|
||||||
newnode->filename = NULL;
|
newnode->filename = NULL;
|
||||||
newnode->fileage = NULL;
|
|
||||||
newnode->filebot = NULL;
|
|
||||||
|
|
||||||
newnode->prev = prevnode;
|
|
||||||
newnode->next = NULL;
|
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,6 +706,7 @@ openfilestruct *make_new_opennode(openfilestruct *prevnode)
|
||||||
void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
||||||
openfilestruct *end)
|
openfilestruct *end)
|
||||||
{
|
{
|
||||||
|
assert(newnode != NULL && begin != NULL);
|
||||||
newnode->next = end;
|
newnode->next = end;
|
||||||
newnode->prev = begin;
|
newnode->prev = begin;
|
||||||
begin->next = newnode;
|
begin->next = newnode;
|
||||||
|
@ -719,240 +714,203 @@ void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
||||||
end->prev = newnode;
|
end->prev = newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlink a node from the rest of the openfilestruct. */
|
/* Unlink a node from the rest of the openfilestruct, and delete it. */
|
||||||
void unlink_opennode(const openfilestruct *fileptr)
|
void unlink_opennode(openfilestruct *fileptr)
|
||||||
{
|
{
|
||||||
assert(fileptr != NULL);
|
assert(fileptr != NULL && fileptr->prev != NULL && fileptr->next != NULL && fileptr != fileptr->prev && fileptr != fileptr->next);
|
||||||
|
fileptr->prev->next = fileptr->next;
|
||||||
if (fileptr->prev != NULL)
|
fileptr->next->prev = fileptr->prev;
|
||||||
fileptr->prev->next = fileptr->next;
|
delete_opennode(fileptr);
|
||||||
|
|
||||||
if (fileptr->next != NULL)
|
|
||||||
fileptr->next->prev = fileptr->prev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete a node from the openfilestruct. */
|
/* Delete a node from the openfilestruct. */
|
||||||
void delete_opennode(openfilestruct *fileptr)
|
void delete_opennode(openfilestruct *fileptr)
|
||||||
{
|
{
|
||||||
if (fileptr != NULL) {
|
assert(fileptr != NULL && fileptr->filename != NULL && fileptr->fileage != NULL);
|
||||||
if (fileptr->filename != NULL)
|
free(fileptr->filename);
|
||||||
free(fileptr->filename);
|
free_filestruct(fileptr->fileage);
|
||||||
if (fileptr->fileage != NULL)
|
free(fileptr);
|
||||||
free_filestruct(fileptr->fileage);
|
|
||||||
free(fileptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deallocate all memory associated with this and later files,
|
#ifdef DEBUG
|
||||||
* including the lines of text. */
|
/* Deallocate all memory associated with this and later files, including
|
||||||
|
* the lines of text. */
|
||||||
void free_openfilestruct(openfilestruct *src)
|
void free_openfilestruct(openfilestruct *src)
|
||||||
{
|
{
|
||||||
if (src != NULL) {
|
assert(src != NULL);
|
||||||
while (src->next != NULL) {
|
while (src != src->next) {
|
||||||
src = src->next;
|
src = src->next;
|
||||||
delete_opennode(src->prev);
|
delete_opennode(src->prev);
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "%s: free'd a node, YAY!\n", "delete_opennode()");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
delete_opennode(src);
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "%s: free'd last node.\n", "delete_opennode()");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
delete_opennode(src);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/* Add/update an entry to the open_files openfilestruct. If update is
|
||||||
* Add/update an entry to the open_files openfilestruct. If update is
|
|
||||||
* FALSE, a new entry is created; otherwise, the current entry is
|
* FALSE, a new entry is created; otherwise, the current entry is
|
||||||
* updated.
|
* updated. */
|
||||||
*/
|
|
||||||
void add_open_file(bool update)
|
void add_open_file(bool update)
|
||||||
{
|
{
|
||||||
openfilestruct *tmp;
|
if (open_files == NULL && update)
|
||||||
|
|
||||||
if (fileage == NULL || current == NULL || filename == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* if no entries, make the first one */
|
/* If there are no entries in open_files, make the first one. */
|
||||||
if (open_files == NULL)
|
if (open_files == NULL) {
|
||||||
open_files = make_new_opennode(NULL);
|
open_files = make_new_opennode();
|
||||||
|
splice_opennode(open_files, open_files, 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 entry. */
|
||||||
/* otherwise, if we're not updating, make a new entry for
|
} else if (!update) {
|
||||||
open_files and splice it in after the current one */
|
splice_opennode(open_files, make_new_opennode(),
|
||||||
|
open_files->next);
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "filename is %s\n", open_files->filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tmp = make_new_opennode(NULL);
|
|
||||||
splice_opennode(open_files, tmp, open_files->next);
|
|
||||||
open_files = open_files->next;
|
open_files = open_files->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save current filename */
|
/* Save the current filename. */
|
||||||
open_files->filename = mallocstrcpy(open_files->filename, filename);
|
open_files->filename = mallocstrcpy(open_files->filename, filename);
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
/* save the file's stat */
|
/* Save the current file's stat. */
|
||||||
open_files->originalfilestat = originalfilestat;
|
open_files->originalfilestat = originalfilestat;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* save current total number of lines */
|
/* Save the current file buffer. */
|
||||||
open_files->file_totlines = totlines;
|
open_files->fileage = fileage;
|
||||||
|
open_files->filebot = filebot;
|
||||||
|
|
||||||
/* save current total size */
|
/* Save the current top of the edit window. */
|
||||||
open_files->file_totsize = totsize;
|
open_files->edittop = edittop;
|
||||||
|
|
||||||
/* save current x-coordinate position */
|
/* Save the current line. */
|
||||||
open_files->file_current_x = current_x;
|
open_files->current = current;
|
||||||
|
|
||||||
/* save current y-coordinate position */
|
/* Save the current cursor position. */
|
||||||
open_files->file_current_y = current_y;
|
open_files->current_x = current_x;
|
||||||
|
|
||||||
/* save current place we want */
|
/* Save the current place we want. */
|
||||||
open_files->file_placewewant = placewewant;
|
open_files->placewewant = placewewant;
|
||||||
|
|
||||||
/* save current line number */
|
/* Save the current total number of lines. */
|
||||||
open_files->file_lineno = current->lineno;
|
open_files->totlines = totlines;
|
||||||
|
|
||||||
/* start with default modification status: unmodified, unmarked (if
|
/* Save the current total size. */
|
||||||
available), not in DOS format (if available), and not in Mac
|
open_files->totsize = totsize;
|
||||||
format (if available) */
|
|
||||||
open_files->file_flags = 0;
|
/* Start with no flags saved. */
|
||||||
|
open_files->flags = 0;
|
||||||
|
|
||||||
|
/* Save the current modification status. */
|
||||||
|
if (ISSET(MODIFIED))
|
||||||
|
open_files->flags |= MODIFIED;
|
||||||
|
|
||||||
/* if we're updating, save current modification status, current
|
|
||||||
marking status (if available), and current file format (if
|
|
||||||
available) */
|
|
||||||
if (update) {
|
|
||||||
if (ISSET(MODIFIED))
|
|
||||||
open_files->file_flags |= MODIFIED;
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
if (ISSET(MARK_ISSET)) {
|
/* Save the current marking status and mark, if applicable. */
|
||||||
open_files->file_mark_beginbuf = mark_beginbuf;
|
if (ISSET(MARK_ISSET)) {
|
||||||
open_files->file_mark_beginx = mark_beginx;
|
open_files->flags |= MARK_ISSET;
|
||||||
open_files->file_flags |= MARK_ISSET;
|
open_files->mark_beginbuf = mark_beginbuf;
|
||||||
}
|
open_files->mark_beginx = mark_beginx;
|
||||||
open_files->file_fmt = fmt;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we're not in view mode and not updating, the file contents
|
/* Save the current file format. */
|
||||||
might have changed, so save the filestruct; otherwise, don't */
|
open_files->fmt = fmt;
|
||||||
if (!(ISSET(VIEW_MODE) && !update)) {
|
#endif
|
||||||
/* save current file buffer */
|
|
||||||
open_files->fileage = fileage;
|
|
||||||
open_files->filebot = filebot;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "filename is %s\n", open_files->filename);
|
fprintf(stderr, "filename is %s\n", open_files->filename);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Read the current entry in the open_files structure and set up the
|
||||||
* Read the current entry in the open_files structure and set up the
|
* currently open file using that entry's information. */
|
||||||
* currently open file using that entry's information.
|
|
||||||
*/
|
|
||||||
void load_open_file(void)
|
void load_open_file(void)
|
||||||
{
|
{
|
||||||
if (open_files == NULL)
|
assert(open_files != NULL);
|
||||||
return;
|
|
||||||
|
|
||||||
/* set up the filename, the file buffer, the total number of lines in
|
/* Restore the current filename. */
|
||||||
the file, and the total file size */
|
|
||||||
filename = mallocstrcpy(filename, open_files->filename);
|
filename = mallocstrcpy(filename, open_files->filename);
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
|
/* Restore the current file's stat. */
|
||||||
originalfilestat = open_files->originalfilestat;
|
originalfilestat = open_files->originalfilestat;
|
||||||
#endif
|
#endif
|
||||||
fileage = open_files->fileage;
|
|
||||||
current = fileage;
|
|
||||||
filebot = open_files->filebot;
|
|
||||||
totlines = open_files->file_totlines;
|
|
||||||
totsize = open_files->file_totsize;
|
|
||||||
|
|
||||||
/* restore modification status */
|
/* Restore the current file buffer. */
|
||||||
if (open_files->file_flags & MODIFIED)
|
fileage = open_files->fileage;
|
||||||
|
filebot = open_files->filebot;
|
||||||
|
|
||||||
|
/* Restore the current top of the edit window. */
|
||||||
|
edittop = open_files->edittop;
|
||||||
|
|
||||||
|
/* Restore the current line. */
|
||||||
|
current = open_files->current;
|
||||||
|
|
||||||
|
/* Restore the current cursor position. */
|
||||||
|
current_x = open_files->current_x;
|
||||||
|
|
||||||
|
/* Restore the current place we want. */
|
||||||
|
placewewant = open_files->placewewant;
|
||||||
|
|
||||||
|
/* Restore the current total number of lines. */
|
||||||
|
totlines = open_files->totlines;
|
||||||
|
|
||||||
|
/* Restore the current total size. */
|
||||||
|
totsize = open_files->totsize;
|
||||||
|
|
||||||
|
/* Restore the current modification status. */
|
||||||
|
if (open_files->flags & MODIFIED)
|
||||||
SET(MODIFIED);
|
SET(MODIFIED);
|
||||||
else
|
else
|
||||||
UNSET(MODIFIED);
|
UNSET(MODIFIED);
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
/* restore marking status */
|
/* Restore the current marking status and mark, if applicable. */
|
||||||
if (open_files->file_flags & MARK_ISSET) {
|
if (open_files->flags & MARK_ISSET) {
|
||||||
mark_beginbuf = open_files->file_mark_beginbuf;
|
mark_beginbuf = open_files->mark_beginbuf;
|
||||||
mark_beginx = open_files->file_mark_beginx;
|
mark_beginx = open_files->mark_beginx;
|
||||||
SET(MARK_ISSET);
|
SET(MARK_ISSET);
|
||||||
} else
|
} else
|
||||||
UNSET(MARK_ISSET);
|
UNSET(MARK_ISSET);
|
||||||
|
|
||||||
/* restore file format */
|
/* Restore the current file format. */
|
||||||
fmt = open_files->file_fmt;
|
fmt = open_files->fmt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_COLOR
|
#ifdef ENABLE_COLOR
|
||||||
update_color();
|
update_color();
|
||||||
#endif
|
#endif
|
||||||
|
edit_refresh();
|
||||||
|
|
||||||
/* restore full file position: line number, x-coordinate, y-
|
/* Update the titlebar. */
|
||||||
coordinate, place we want */
|
|
||||||
do_gotopos(open_files->file_lineno, open_files->file_current_x,
|
|
||||||
open_files->file_current_y, open_files->file_placewewant);
|
|
||||||
|
|
||||||
/* update the titlebar */
|
|
||||||
clearok(topwin, FALSE);
|
clearok(topwin, FALSE);
|
||||||
titlebar(NULL);
|
titlebar(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Open either the next or previous file. */
|
||||||
* Open the previous entry in the open_files structure. If closing_file
|
void open_prevnext_file(bool next)
|
||||||
* is FALSE, update the current entry before switching from it.
|
|
||||||
* Otherwise, we are about to close that entry, so don't bother doing
|
|
||||||
* so.
|
|
||||||
*/
|
|
||||||
void open_prevfile(bool closing_file)
|
|
||||||
{
|
{
|
||||||
if (open_files == NULL)
|
add_open_file(TRUE);
|
||||||
return;
|
|
||||||
|
|
||||||
/* if we're not about to close the current entry, update it before
|
assert(open_files != NULL);
|
||||||
doing anything */
|
|
||||||
if (!closing_file)
|
|
||||||
add_open_file(TRUE);
|
|
||||||
|
|
||||||
if (open_files->prev == NULL && open_files->next == NULL) {
|
/* If only one file is open, indicate it on the statusbar and get
|
||||||
|
* out. */
|
||||||
/* only one file open */
|
if (open_files == open_files->next) {
|
||||||
if (!closing_file)
|
statusbar(_("No more open files"));
|
||||||
statusbar(_("No more open file buffers"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_files->prev != NULL) {
|
/* Switch to the next or previous file, depending on the value of
|
||||||
open_files = open_files->prev;
|
* next. */
|
||||||
|
open_files = next ? open_files->next : open_files->prev;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "filename is %s\n", open_files->filename);
|
fprintf(stderr, "filename is %s\n", open_files->filename);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
/* Load the file we switched to. */
|
||||||
|
|
||||||
else if (open_files->next != NULL) {
|
|
||||||
|
|
||||||
/* if we're at the beginning, wrap around to the end */
|
|
||||||
while (open_files->next != NULL)
|
|
||||||
open_files = open_files->next;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "filename is %s\n", open_files->filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
load_open_file();
|
load_open_file();
|
||||||
|
|
||||||
|
/* And indicate the switch on the statusbar. */
|
||||||
statusbar(_("Switched to %s"),
|
statusbar(_("Switched to %s"),
|
||||||
((open_files->filename[0] == '\0') ? _("New Buffer") :
|
((open_files->filename[0] == '\0') ? _("New Buffer") :
|
||||||
open_files->filename));
|
open_files->filename));
|
||||||
|
@ -962,102 +920,41 @@ void open_prevfile(bool closing_file)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Open the previous entry in the open_files structure. This function
|
||||||
|
* is used by the shortcut list. */
|
||||||
void open_prevfile_void(void)
|
void open_prevfile_void(void)
|
||||||
{
|
{
|
||||||
open_prevfile(FALSE);
|
open_prevnext_file(FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Open the next entry in the open_files structure. If closing_file is
|
|
||||||
* FALSE, update the current entry before switching from it. Otherwise,
|
|
||||||
* we are about to close that entry, so don't bother doing so.
|
|
||||||
*/
|
|
||||||
void open_nextfile(bool closing_file)
|
|
||||||
{
|
|
||||||
if (open_files == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* if we're not about to close the current entry, update it before
|
|
||||||
doing anything */
|
|
||||||
if (!closing_file)
|
|
||||||
add_open_file(TRUE);
|
|
||||||
|
|
||||||
if (open_files->prev == NULL && open_files->next == NULL) {
|
|
||||||
|
|
||||||
/* only one file open */
|
|
||||||
if (!closing_file)
|
|
||||||
statusbar(_("No more open file buffers"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (open_files->next != NULL) {
|
|
||||||
open_files = open_files->next;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "filename is %s\n", open_files->filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (open_files->prev != NULL) {
|
|
||||||
|
|
||||||
/* if we're at the end, wrap around to the beginning */
|
|
||||||
while (open_files->prev != NULL) {
|
|
||||||
open_files = open_files->prev;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "filename is %s\n", open_files->filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
load_open_file();
|
|
||||||
|
|
||||||
statusbar(_("Switched to %s"),
|
|
||||||
((open_files->filename[0] == '\0') ? _("New Buffer") :
|
|
||||||
open_files->filename));
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
dump_buffer(current);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Open the next entry in the open_files structure. This function is
|
||||||
|
* used by the shortcut list. */
|
||||||
void open_nextfile_void(void)
|
void open_nextfile_void(void)
|
||||||
{
|
{
|
||||||
open_nextfile(FALSE);
|
open_prevnext_file(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Delete an entry from the open_files filestruct. After deletion of an
|
||||||
* Delete an entry from the open_files filestruct. After deletion of an
|
* entry, the next entry is opened. Return TRUE on success or FALSE if
|
||||||
* entry, the next or previous entry is opened, whichever is found first.
|
* there are no more open files. */
|
||||||
* Return TRUE on success or FALSE on error.
|
|
||||||
*/
|
|
||||||
bool close_open_file(void)
|
bool close_open_file(void)
|
||||||
{
|
{
|
||||||
openfilestruct *tmp;
|
assert(open_files != NULL);
|
||||||
|
|
||||||
if (open_files == NULL)
|
/* If only one file is open, get out. */
|
||||||
|
if (open_files == open_files->next)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* make sure open_files->fileage and fileage, and open_files->filebot
|
/* Open the next file. */
|
||||||
and filebot, are in sync; they might not be if lines have been cut
|
open_nextfile_void();
|
||||||
from the top or bottom of the file */
|
|
||||||
open_files->fileage = fileage;
|
|
||||||
open_files->filebot = filebot;
|
|
||||||
|
|
||||||
tmp = open_files;
|
/* Close the file we had open before. */
|
||||||
if (open_files->next != NULL)
|
unlink_opennode(open_files->prev);
|
||||||
open_nextfile(TRUE);
|
|
||||||
else if (open_files->prev != NULL)
|
|
||||||
open_prevfile(TRUE);
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
unlink_opennode(tmp);
|
|
||||||
delete_opennode(tmp);
|
|
||||||
|
|
||||||
|
/* Reinitialize the shortcut list. */
|
||||||
shortcut_init(FALSE);
|
shortcut_init(FALSE);
|
||||||
display_main_list();
|
display_main_list();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
#endif /* ENABLE_MULTIBUFFER */
|
#endif /* ENABLE_MULTIBUFFER */
|
||||||
|
|
17
src/global.c
17
src/global.c
|
@ -382,19 +382,14 @@ void shortcut_init(bool unjustify)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Translators: try to keep this string under 10 characters long */
|
||||||
|
sc_init_one(&main_list, NANO_EXIT_KEY,
|
||||||
#ifdef ENABLE_MULTIBUFFER
|
#ifdef ENABLE_MULTIBUFFER
|
||||||
if (open_files != NULL && (open_files->prev != NULL ||
|
open_files != NULL && open_files != open_files->next ?
|
||||||
open_files->next != NULL))
|
N_("Close") :
|
||||||
/* Translators: try to keep this string under 10 characters long */
|
|
||||||
sc_init_one(&main_list, NANO_EXIT_KEY, N_("Close"),
|
|
||||||
IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY,
|
|
||||||
NANO_NO_KEY, VIEW, do_exit);
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
/* Translators: try to keep this string under 10 characters long */
|
exit_msg, IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY,
|
||||||
sc_init_one(&main_list, NANO_EXIT_KEY, exit_msg,
|
NANO_NO_KEY, VIEW, do_exit);
|
||||||
IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY,
|
|
||||||
NANO_NO_KEY, VIEW, do_exit);
|
|
||||||
|
|
||||||
/* Translators: try to keep this string under 10 characters long */
|
/* Translators: try to keep this string under 10 characters long */
|
||||||
sc_init_one(&main_list, NANO_WRITEOUT_KEY, N_("WriteOut"),
|
sc_init_one(&main_list, NANO_WRITEOUT_KEY, N_("WriteOut"),
|
||||||
|
|
53
src/nano.c
53
src/nano.c
|
@ -150,7 +150,7 @@ void die(const char *msg, ...)
|
||||||
fileage = open_files->fileage;
|
fileage = open_files->fileage;
|
||||||
filebot = open_files->filebot;
|
filebot = open_files->filebot;
|
||||||
/* save the file if it's been modified */
|
/* save the file if it's been modified */
|
||||||
if (open_files->file_flags & MODIFIED)
|
if (open_files->flags & MODIFIED)
|
||||||
die_save_file(open_files->filename);
|
die_save_file(open_files->filename);
|
||||||
}
|
}
|
||||||
open_files = open_files->next;
|
open_files = open_files->next;
|
||||||
|
@ -520,28 +520,22 @@ void help_init(void)
|
||||||
filestruct *make_new_node(filestruct *prevnode)
|
filestruct *make_new_node(filestruct *prevnode)
|
||||||
{
|
{
|
||||||
filestruct *newnode = (filestruct *)nmalloc(sizeof(filestruct));
|
filestruct *newnode = (filestruct *)nmalloc(sizeof(filestruct));
|
||||||
|
|
||||||
newnode->data = NULL;
|
newnode->data = NULL;
|
||||||
newnode->prev = prevnode;
|
newnode->prev = prevnode;
|
||||||
newnode->next = NULL;
|
newnode->next = NULL;
|
||||||
newnode->lineno = prevnode != NULL ? prevnode->lineno + 1 : 1;
|
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a copy of a node to a pointer (space will be malloc()ed). */
|
/* Make a copy of a filestruct node. */
|
||||||
filestruct *copy_node(const filestruct *src)
|
filestruct *copy_node(const filestruct *src)
|
||||||
{
|
{
|
||||||
filestruct *dst = (filestruct *)nmalloc(sizeof(filestruct));
|
filestruct *dst = (filestruct *)nmalloc(sizeof(filestruct));
|
||||||
|
|
||||||
assert(src != NULL);
|
assert(src != NULL);
|
||||||
|
dst->data = mallocstrcpy(NULL, src->data);
|
||||||
dst->data = charalloc(strlen(src->data) + 1);
|
|
||||||
dst->next = src->next;
|
dst->next = src->next;
|
||||||
dst->prev = src->prev;
|
dst->prev = src->prev;
|
||||||
strcpy(dst->data, src->data);
|
|
||||||
dst->lineno = src->lineno;
|
dst->lineno = src->lineno;
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,12 +543,10 @@ filestruct *copy_node(const filestruct *src)
|
||||||
void splice_node(filestruct *begin, filestruct *newnode, filestruct
|
void splice_node(filestruct *begin, filestruct *newnode, filestruct
|
||||||
*end)
|
*end)
|
||||||
{
|
{
|
||||||
if (newnode != NULL) {
|
assert(newnode != NULL && begin != NULL);
|
||||||
newnode->next = end;
|
newnode->next = end;
|
||||||
newnode->prev = begin;
|
newnode->prev = begin;
|
||||||
}
|
begin->next = newnode;
|
||||||
if (begin != NULL)
|
|
||||||
begin->next = newnode;
|
|
||||||
if (end != NULL)
|
if (end != NULL)
|
||||||
end->prev = newnode;
|
end->prev = newnode;
|
||||||
}
|
}
|
||||||
|
@ -563,10 +555,8 @@ void splice_node(filestruct *begin, filestruct *newnode, filestruct
|
||||||
void unlink_node(const filestruct *fileptr)
|
void unlink_node(const filestruct *fileptr)
|
||||||
{
|
{
|
||||||
assert(fileptr != NULL);
|
assert(fileptr != NULL);
|
||||||
|
|
||||||
if (fileptr->prev != NULL)
|
if (fileptr->prev != NULL)
|
||||||
fileptr->prev->next = fileptr->next;
|
fileptr->prev->next = fileptr->next;
|
||||||
|
|
||||||
if (fileptr->next != NULL)
|
if (fileptr->next != NULL)
|
||||||
fileptr->next->prev = fileptr->prev;
|
fileptr->next->prev = fileptr->prev;
|
||||||
}
|
}
|
||||||
|
@ -574,11 +564,10 @@ void unlink_node(const filestruct *fileptr)
|
||||||
/* Delete a node from the filestruct. */
|
/* Delete a node from the filestruct. */
|
||||||
void delete_node(filestruct *fileptr)
|
void delete_node(filestruct *fileptr)
|
||||||
{
|
{
|
||||||
if (fileptr != NULL) {
|
assert(fileptr != NULL && fileptr->data != NULL);
|
||||||
if (fileptr->data != NULL)
|
if (fileptr->data != NULL)
|
||||||
free(fileptr->data);
|
free(fileptr->data);
|
||||||
free(fileptr);
|
free(fileptr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Okay, now let's duplicate a whole struct! */
|
/* Okay, now let's duplicate a whole struct! */
|
||||||
|
@ -608,19 +597,13 @@ filestruct *copy_filestruct(const filestruct *src)
|
||||||
/* Frees a filestruct. */
|
/* Frees a filestruct. */
|
||||||
void free_filestruct(filestruct *src)
|
void free_filestruct(filestruct *src)
|
||||||
{
|
{
|
||||||
if (src != NULL) {
|
assert(src != NULL);
|
||||||
while (src->next != NULL) {
|
|
||||||
src = src->next;
|
while (src->next != NULL) {
|
||||||
delete_node(src->prev);
|
src = src->next;
|
||||||
#ifdef DEBUG
|
delete_node(src->prev);
|
||||||
fprintf(stderr, "%s: free'd a node, YAY!\n", "delete_node()");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
delete_node(src);
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "%s: free'd last node.\n", "delete_node()");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
delete_node(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Partition a filestruct so it begins at (top, top_x) and ends at (bot,
|
/* Partition a filestruct so it begins at (top, top_x) and ends at (bot,
|
||||||
|
|
31
src/nano.h
31
src/nano.h
|
@ -175,30 +175,31 @@ typedef struct openfilestruct {
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
struct stat originalfilestat;
|
struct stat originalfilestat;
|
||||||
#endif
|
#endif
|
||||||
struct openfilestruct *next; /* Next node. */
|
struct openfilestruct *next;
|
||||||
struct openfilestruct *prev; /* Previous node. */
|
/* Next node. */
|
||||||
struct filestruct *fileage; /* Current file. */
|
struct openfilestruct *prev;
|
||||||
struct filestruct *filebot; /* Current file's last line. */
|
/* Previous node. */
|
||||||
|
filestruct *fileage; /* Current file. */
|
||||||
|
filestruct *filebot; /* Current file's last line. */
|
||||||
|
filestruct *edittop; /* Current top of edit window. */
|
||||||
|
filestruct *current; /* Current file's line. */
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
struct filestruct *file_mark_beginbuf;
|
filestruct *mark_beginbuf;
|
||||||
/* Current file's beginning marked
|
/* Current file's beginning marked
|
||||||
* line. */
|
* line. */
|
||||||
size_t file_mark_beginx; /* Current file's beginning marked
|
size_t mark_beginx; /* Current file's beginning marked
|
||||||
* line's x-coordinate position. */
|
* line's x-coordinate position. */
|
||||||
#endif
|
#endif
|
||||||
size_t file_current_x; /* Current file's x-coordinate
|
size_t current_x; /* Current file's x-coordinate
|
||||||
* position. */
|
* position. */
|
||||||
int file_current_y; /* Current file's y-coordinate
|
size_t placewewant; /* Current file's place we want. */
|
||||||
* position. */
|
int totlines; /* Current file's total number of
|
||||||
size_t file_placewewant; /* Current file's place we want. */
|
|
||||||
int file_totlines; /* Current file's total number of
|
|
||||||
* lines. */
|
* lines. */
|
||||||
long file_totsize; /* Current file's total size. */
|
long totsize; /* Current file's total size. */
|
||||||
int file_lineno; /* Current file's line number. */
|
long flags; /* Current file's flags: modification
|
||||||
long file_flags; /* Current file's flags: modification
|
|
||||||
* status (and marking status, if
|
* status (and marking status, if
|
||||||
* available). */
|
* available). */
|
||||||
file_format file_fmt; /* Current file's format. */
|
file_format fmt; /* Current file's format. */
|
||||||
} openfilestruct;
|
} openfilestruct;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -190,17 +190,18 @@ void do_insertfile(
|
||||||
);
|
);
|
||||||
void do_insertfile_void(void);
|
void do_insertfile_void(void);
|
||||||
#ifdef ENABLE_MULTIBUFFER
|
#ifdef ENABLE_MULTIBUFFER
|
||||||
openfilestruct *make_new_opennode(openfilestruct *prevnode);
|
openfilestruct *make_new_opennode(void);
|
||||||
void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
||||||
openfilestruct *end);
|
openfilestruct *end);
|
||||||
void unlink_opennode(const openfilestruct *fileptr);
|
void unlink_opennode(openfilestruct *fileptr);
|
||||||
void delete_opennode(openfilestruct *fileptr);
|
void delete_opennode(openfilestruct *fileptr);
|
||||||
|
#ifdef DEBUG
|
||||||
void free_openfilestruct(openfilestruct *src);
|
void free_openfilestruct(openfilestruct *src);
|
||||||
|
#endif
|
||||||
void add_open_file(bool update);
|
void add_open_file(bool update);
|
||||||
void load_open_file(void);
|
void load_open_file(void);
|
||||||
void open_prevfile(bool closing_file);
|
void open_prevnext_file(bool next);
|
||||||
void open_prevfile_void(void);
|
void open_prevfile_void(void);
|
||||||
void open_nextfile(bool closing_file);
|
|
||||||
void open_nextfile_void(void);
|
void open_nextfile_void(void);
|
||||||
bool close_open_file(void);
|
bool close_open_file(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue