2000-08-06 21:13:45 +00:00
|
|
|
/* $Id$ */
|
2000-06-06 05:53:49 +00:00
|
|
|
/**************************************************************************
|
|
|
|
* cut.c *
|
|
|
|
* *
|
2004-01-09 23:04:55 +00:00
|
|
|
* Copyright (C) 1999-2004 Chris Allegretta *
|
2000-06-06 05:53:49 +00:00
|
|
|
* 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 *
|
2001-10-24 11:33:54 +00:00
|
|
|
* the Free Software Foundation; either version 2, or (at your option) *
|
2000-06-06 05:53:49 +00:00
|
|
|
* 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. *
|
|
|
|
* *
|
|
|
|
**************************************************************************/
|
|
|
|
|
2001-04-28 18:03:52 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2000-06-06 05:53:49 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2002-07-19 01:08:59 +00:00
|
|
|
#include <assert.h>
|
2000-06-06 05:53:49 +00:00
|
|
|
#include "proto.h"
|
|
|
|
#include "nano.h"
|
|
|
|
|
2004-08-12 03:27:54 +00:00
|
|
|
static bool keep_cutbuffer = FALSE;
|
2004-05-29 15:36:58 +00:00
|
|
|
/* Should we keep the contents of the cutbuffer? */
|
2004-11-04 13:47:28 +00:00
|
|
|
static cut_type marked_cut = CUT_LINE;
|
|
|
|
/* What type of cut is in the cutbuffer? */
|
2003-04-15 01:15:09 +00:00
|
|
|
#ifndef NANO_SMALL
|
2004-09-30 22:07:21 +00:00
|
|
|
static bool concatenate_cut = FALSE;
|
2004-05-29 15:36:58 +00:00
|
|
|
/* Should we add this cut string to the end of the last one? */
|
2003-04-15 01:15:09 +00:00
|
|
|
#endif
|
2002-12-22 16:30:00 +00:00
|
|
|
static filestruct *cutbottom = NULL;
|
2004-05-29 15:36:58 +00:00
|
|
|
/* Pointer to end of cutbuffer. */
|
|
|
|
|
|
|
|
void cutbuffer_reset(void)
|
|
|
|
{
|
|
|
|
keep_cutbuffer = FALSE;
|
|
|
|
}
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
filestruct *get_cutbottom(void)
|
|
|
|
{
|
|
|
|
return cutbottom;
|
|
|
|
}
|
|
|
|
|
2004-08-12 03:27:54 +00:00
|
|
|
void add_to_cutbuffer(filestruct *inptr, bool allow_concat)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
2003-12-24 08:03:54 +00:00
|
|
|
fprintf(stderr, "add_to_cutbuffer(): inptr->data = %s\n", inptr->data);
|
2000-06-06 05:53:49 +00:00
|
|
|
#endif
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
if (cutbuffer == NULL)
|
2000-06-06 05:53:49 +00:00
|
|
|
cutbuffer = inptr;
|
2003-04-15 01:15:09 +00:00
|
|
|
#ifndef NANO_SMALL
|
2004-03-30 04:17:10 +00:00
|
|
|
else if (allow_concat && concatenate_cut) {
|
2003-04-15 01:15:09 +00:00
|
|
|
/* Just tack the text in inptr onto the text in cutbottom,
|
2004-08-12 03:27:54 +00:00
|
|
|
* unless allow_concat is FALSE. */
|
2003-04-15 01:15:09 +00:00
|
|
|
cutbottom->data = charealloc(cutbottom->data,
|
|
|
|
strlen(cutbottom->data) + strlen(inptr->data) + 1);
|
|
|
|
strcat(cutbottom->data, inptr->data);
|
|
|
|
return;
|
2003-12-24 08:03:54 +00:00
|
|
|
}
|
2003-04-15 01:15:09 +00:00
|
|
|
#endif
|
2003-12-24 08:03:54 +00:00
|
|
|
else {
|
2000-06-06 05:53:49 +00:00
|
|
|
cutbottom->next = inptr;
|
|
|
|
inptr->prev = cutbottom;
|
|
|
|
}
|
|
|
|
cutbottom = inptr;
|
2003-12-24 08:03:54 +00:00
|
|
|
cutbottom->next = NULL;
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NANO_SMALL
|
2002-07-19 01:08:59 +00:00
|
|
|
/* Cut a marked segment instead of a whole line.
|
2002-12-22 16:30:00 +00:00
|
|
|
*
|
2002-07-19 01:08:59 +00:00
|
|
|
* The first cut character is top->data[top_x]. Unless top == bot, the
|
|
|
|
* last cut line has length bot_x. That is, if bot_x > 0 then we cut to
|
|
|
|
* bot->data[bot_x - 1].
|
|
|
|
*
|
2003-12-24 08:03:54 +00:00
|
|
|
* We maintain totsize, totlines, filebot, the magicline, and line
|
|
|
|
* numbers. Also, we set current and current_x so the cursor will be on
|
|
|
|
* the first character after what was cut. We do not do any screen
|
|
|
|
* updates.
|
2002-07-19 01:08:59 +00:00
|
|
|
*
|
2004-01-09 23:04:55 +00:00
|
|
|
* Note cutbuffer might not be NULL if cut to end is used. */
|
2003-12-24 08:03:54 +00:00
|
|
|
void cut_marked_segment(void)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2003-12-24 08:03:54 +00:00
|
|
|
filestruct *top;
|
|
|
|
filestruct *bot;
|
|
|
|
filestruct *tmp;
|
|
|
|
size_t top_x;
|
|
|
|
size_t bot_x;
|
2002-07-19 01:08:59 +00:00
|
|
|
size_t newsize;
|
2001-06-21 23:58:47 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* If the mark doesn't cover any text, get out. */
|
|
|
|
if (current == mark_beginbuf && current_x == mark_beginx)
|
2002-07-19 01:08:59 +00:00
|
|
|
return;
|
2003-12-24 08:03:54 +00:00
|
|
|
assert(current != NULL && mark_beginbuf != NULL);
|
2001-06-21 23:58:47 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Set up the top and bottom lines and coordinates of the marked
|
|
|
|
* text. */
|
|
|
|
mark_order((const filestruct **)&top, &top_x,
|
|
|
|
(const filestruct **)&bot, &bot_x);
|
2001-06-21 23:58:47 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Make the first cut line manually. Move the cut part of the top
|
|
|
|
* line into tmp, and set newsize to that partial line's length. */
|
2000-06-06 05:53:49 +00:00
|
|
|
tmp = copy_node(top);
|
2002-07-19 01:08:59 +00:00
|
|
|
newsize = (top == bot ? bot_x - top_x : strlen(top->data + top_x));
|
2003-12-24 08:03:54 +00:00
|
|
|
charmove(tmp->data, tmp->data + top_x, newsize);
|
2002-07-19 01:08:59 +00:00
|
|
|
null_at(&tmp->data, newsize);
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Add the contents of tmp to the cutbuffer. Note that cutbuffer
|
|
|
|
* might be non-NULL if we have cut to end enabled. */
|
|
|
|
if (cutbuffer == NULL) {
|
|
|
|
cutbuffer = tmp;
|
|
|
|
cutbottom = tmp;
|
|
|
|
} else {
|
|
|
|
cutbottom->next = tmp;
|
|
|
|
tmp->prev = cutbottom;
|
|
|
|
cutbottom = tmp;
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* And make the top remainder line manually too. Update current_x
|
|
|
|
* and totlines to account for all the cut text, and update totsize
|
|
|
|
* to account for the length of the cut part of the first line. */
|
|
|
|
current_x = top_x;
|
|
|
|
totsize -= newsize;
|
|
|
|
totlines -= bot->lineno - top->lineno;
|
|
|
|
|
|
|
|
/* Now set newsize to be the length of the top remainder line plus
|
|
|
|
* the bottom remainder line, plus one for the null terminator. */
|
|
|
|
newsize = top_x + strlen(bot->data + bot_x) + 1;
|
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
if (top == bot) {
|
2003-12-24 08:03:54 +00:00
|
|
|
/* In this case, we're only cutting one line or part of one
|
|
|
|
* line, so the remainder line is shorter. This means that we
|
|
|
|
* must move text from the end forward first. */
|
|
|
|
charmove(top->data + top_x, bot->data + bot_x, newsize - top_x);
|
|
|
|
top->data = charealloc(top->data, newsize);
|
|
|
|
|
|
|
|
cutbottom->next = NULL;
|
2002-07-19 01:08:59 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
dump_buffer(cutbuffer);
|
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
return;
|
2001-05-29 04:21:44 +00:00
|
|
|
}
|
2001-05-17 03:41:00 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Update totsize to account for the cut part of the last line. */
|
|
|
|
totsize -= bot_x + 1;
|
2001-05-17 03:41:00 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Here, the top remainder line might get longer (if the bottom
|
|
|
|
* remainder line is added to the end of it), so we realloc() it
|
|
|
|
* first. */
|
|
|
|
top->data = charealloc(top->data, newsize);
|
|
|
|
charmove(top->data + top_x, bot->data + bot_x, newsize - top_x);
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
assert(cutbottom != NULL && cutbottom->next != NULL);
|
|
|
|
/* We're cutting multiple lines, so in particular the next line is
|
|
|
|
* cut too. */
|
|
|
|
cutbottom->next->prev = cutbottom;
|
|
|
|
|
|
|
|
/* Update totsize to account for all the complete lines that have
|
|
|
|
* been cut. After this, totsize is fully up to date. */
|
|
|
|
for (tmp = top->next; tmp != bot; tmp = tmp->next)
|
|
|
|
totsize -= strlen(tmp->data) + 1;
|
|
|
|
|
|
|
|
/* Make the last cut line manually. */
|
|
|
|
null_at(&bot->data, bot_x);
|
|
|
|
|
|
|
|
/* Move the rest of the cut text (other than the cut part of the top
|
|
|
|
* line) from the buffer to the end of the cutbuffer, and fix the
|
|
|
|
* edit buffer to account for the cut text. */
|
|
|
|
top->next = bot->next;
|
|
|
|
cutbottom = bot;
|
|
|
|
cutbottom->next = NULL;
|
|
|
|
if (top->next != NULL)
|
|
|
|
top->next->prev = top;
|
|
|
|
renumber(top);
|
|
|
|
current = top;
|
|
|
|
|
|
|
|
/* If the bottom line of the cut was the magicline, set filebot
|
|
|
|
* properly, and add a new magicline if the top remainder line
|
|
|
|
* (which is now the new bottom line) is non-blank. */
|
|
|
|
if (bot == filebot) {
|
|
|
|
filebot = top;
|
|
|
|
assert(bot_x == 0);
|
|
|
|
if (top_x > 0)
|
|
|
|
new_magicline();
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
2003-04-15 01:15:09 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
dump_buffer(cutbuffer);
|
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-07-02 14:31:03 +00:00
|
|
|
void do_cut_text(void)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2002-07-19 01:08:59 +00:00
|
|
|
filestruct *fileptr;
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
assert(current != NULL && current->data != NULL);
|
2001-06-21 15:07:40 +00:00
|
|
|
|
2004-09-30 22:07:21 +00:00
|
|
|
check_statusblank();
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2004-05-29 15:36:58 +00:00
|
|
|
if (!keep_cutbuffer) {
|
2000-06-06 05:53:49 +00:00
|
|
|
free_filestruct(cutbuffer);
|
|
|
|
cutbuffer = NULL;
|
2004-11-04 13:47:28 +00:00
|
|
|
marked_cut = CUT_LINE;
|
2003-04-15 01:15:09 +00:00
|
|
|
#ifndef NANO_SMALL
|
2004-03-30 04:17:10 +00:00
|
|
|
concatenate_cut = FALSE;
|
2003-04-15 01:15:09 +00:00
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
#ifdef DEBUG
|
2003-08-05 19:31:12 +00:00
|
|
|
fprintf(stderr, "Blew away cutbuffer =)\n");
|
2000-06-06 05:53:49 +00:00
|
|
|
#endif
|
|
|
|
}
|
2000-08-07 14:58:26 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* You can't cut the magicline except with the mark. But trying
|
2004-05-29 15:36:58 +00:00
|
|
|
* does clear the cutbuffer if keep_cutbuffer is FALSE. */
|
2002-07-19 01:08:59 +00:00
|
|
|
if (current == filebot
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
&& !ISSET(MARK_ISSET)
|
|
|
|
#endif
|
|
|
|
)
|
2004-07-02 14:31:03 +00:00
|
|
|
return;
|
2000-08-07 14:58:26 +00:00
|
|
|
|
2004-05-29 15:36:58 +00:00
|
|
|
keep_cutbuffer = TRUE;
|
2003-04-15 01:15:09 +00:00
|
|
|
|
2000-06-06 05:53:49 +00:00
|
|
|
#ifndef NANO_SMALL
|
2000-07-24 18:28:30 +00:00
|
|
|
if (ISSET(CUT_TO_END) && !ISSET(MARK_ISSET)) {
|
2004-10-30 01:03:15 +00:00
|
|
|
assert(current_x <= strlen(current->data));
|
2001-06-10 20:41:20 +00:00
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
if (current->data[current_x] == '\0') {
|
|
|
|
/* If the line is empty and we didn't just cut a non-blank
|
2003-12-24 08:03:54 +00:00
|
|
|
* line, create a dummy blank line and add it to the
|
|
|
|
* cutbuffer. */
|
2004-11-04 13:47:28 +00:00
|
|
|
if (marked_cut != CUT_MARKED && current->next != filebot) {
|
2002-07-19 01:08:59 +00:00
|
|
|
filestruct *junk = make_new_node(current);
|
2001-06-21 15:07:40 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
junk->data = charalloc(1);
|
2002-06-13 00:40:19 +00:00
|
|
|
junk->data[0] = '\0';
|
2004-03-30 04:17:10 +00:00
|
|
|
add_to_cutbuffer(junk, TRUE);
|
2002-07-19 01:08:59 +00:00
|
|
|
#ifdef DEBUG
|
2001-06-21 15:07:40 +00:00
|
|
|
dump_buffer(cutbuffer);
|
2002-07-19 01:08:59 +00:00
|
|
|
#endif
|
2001-06-10 20:41:20 +00:00
|
|
|
}
|
2001-06-21 15:07:40 +00:00
|
|
|
|
2000-07-25 03:20:07 +00:00
|
|
|
do_delete();
|
2004-11-04 13:47:28 +00:00
|
|
|
marked_cut = CUT_TO_END;
|
2004-07-02 14:31:03 +00:00
|
|
|
return;
|
2000-10-26 01:44:42 +00:00
|
|
|
} else {
|
2000-07-25 03:20:07 +00:00
|
|
|
SET(MARK_ISSET);
|
|
|
|
|
|
|
|
mark_beginx = strlen(current->data);
|
|
|
|
mark_beginbuf = current;
|
|
|
|
}
|
2000-07-12 02:09:17 +00:00
|
|
|
}
|
2001-10-22 03:15:31 +00:00
|
|
|
|
2000-06-06 05:53:49 +00:00
|
|
|
if (ISSET(MARK_ISSET)) {
|
2003-12-24 08:03:54 +00:00
|
|
|
cut_marked_segment();
|
2000-06-06 05:53:49 +00:00
|
|
|
|
|
|
|
placewewant = xplustabs();
|
|
|
|
UNSET(MARK_ISSET);
|
2000-07-27 04:09:23 +00:00
|
|
|
|
2003-04-15 01:15:09 +00:00
|
|
|
/* If we just did a marked cut of part of a line, we should add
|
2003-12-24 08:03:54 +00:00
|
|
|
* the first line of any cut done immediately afterward to the
|
|
|
|
* end of this cut, as Pico does. */
|
2004-11-04 13:47:28 +00:00
|
|
|
if (current == mark_beginbuf && current_x <
|
|
|
|
strlen(current->data))
|
2004-03-30 04:17:10 +00:00
|
|
|
concatenate_cut = TRUE;
|
2004-11-04 13:47:28 +00:00
|
|
|
marked_cut = CUT_MARKED;
|
2003-12-24 08:03:54 +00:00
|
|
|
edit_refresh();
|
2002-12-22 16:30:00 +00:00
|
|
|
set_modified();
|
2004-07-02 14:31:03 +00:00
|
|
|
return;
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
2002-07-19 01:08:59 +00:00
|
|
|
#endif /* !NANO_SMALL */
|
|
|
|
|
|
|
|
totlines--;
|
|
|
|
totsize -= strlen(current->data) + 1;
|
|
|
|
fileptr = current;
|
|
|
|
current = current->next;
|
|
|
|
current->prev = fileptr->prev;
|
2004-03-30 04:17:10 +00:00
|
|
|
add_to_cutbuffer(fileptr, TRUE);
|
2002-07-19 01:08:59 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
dump_buffer(cutbuffer);
|
|
|
|
#endif
|
2002-11-04 16:05:42 +00:00
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
if (fileptr == fileage)
|
|
|
|
fileage = current;
|
|
|
|
else
|
|
|
|
current->prev->next = current;
|
2000-06-06 05:53:49 +00:00
|
|
|
|
|
|
|
if (fileptr == edittop)
|
|
|
|
edittop = current;
|
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
renumber(current);
|
2003-01-26 03:54:00 +00:00
|
|
|
current_x = 0;
|
2000-06-06 05:53:49 +00:00
|
|
|
edit_refresh();
|
|
|
|
set_modified();
|
2004-11-04 13:47:28 +00:00
|
|
|
marked_cut = CUT_LINE;
|
2003-04-15 01:15:09 +00:00
|
|
|
#ifndef NANO_SMALL
|
2004-03-30 04:17:10 +00:00
|
|
|
concatenate_cut = FALSE;
|
2003-04-15 01:15:09 +00:00
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
2004-07-02 14:31:03 +00:00
|
|
|
void do_uncut_text(void)
|
2000-06-06 05:53:49 +00:00
|
|
|
{
|
2003-12-24 08:03:54 +00:00
|
|
|
filestruct *tmp = current;
|
|
|
|
filestruct *newbuf = NULL;
|
|
|
|
filestruct *newend = NULL;
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2003-09-10 20:08:00 +00:00
|
|
|
#ifndef DISABLE_WRAPPING
|
2000-06-06 05:53:49 +00:00
|
|
|
wrap_reset();
|
2003-09-10 20:08:00 +00:00
|
|
|
#endif
|
2004-09-30 22:07:21 +00:00
|
|
|
check_statusblank();
|
2003-12-24 08:03:54 +00:00
|
|
|
if (cutbuffer == NULL || current == NULL)
|
2004-07-02 14:31:03 +00:00
|
|
|
return; /* AIEEEEEEEEEEEE */
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2003-01-14 23:36:11 +00:00
|
|
|
/* If we're uncutting a previously non-marked block, uncut to end if
|
2003-12-24 08:03:54 +00:00
|
|
|
* we're not at the beginning of the line. If we are at the
|
|
|
|
* beginning of the line, set placewewant to 0. Pico does both of
|
|
|
|
* these. */
|
2004-11-04 13:47:28 +00:00
|
|
|
if (marked_cut == CUT_LINE) {
|
2004-10-29 15:42:02 +00:00
|
|
|
if (current_x > 0)
|
2004-11-04 13:47:28 +00:00
|
|
|
marked_cut = CUT_TO_END;
|
2003-01-14 23:36:11 +00:00
|
|
|
else
|
|
|
|
placewewant = 0;
|
|
|
|
}
|
|
|
|
|
2003-04-15 01:15:09 +00:00
|
|
|
/* If we're going to uncut on the magicline, always make a new
|
2003-12-24 08:03:54 +00:00
|
|
|
* magicline in advance, as Pico does. */
|
2003-04-15 01:15:09 +00:00
|
|
|
if (current->next == NULL)
|
|
|
|
new_magicline();
|
|
|
|
|
2004-11-04 13:47:28 +00:00
|
|
|
if (marked_cut == CUT_LINE || cutbuffer->next != NULL) {
|
2002-07-19 01:08:59 +00:00
|
|
|
newbuf = copy_filestruct(cutbuffer);
|
|
|
|
for (newend = newbuf; newend->next != NULL && newend != NULL;
|
|
|
|
newend = newend->next)
|
|
|
|
totlines++;
|
2000-06-06 05:53:49 +00:00
|
|
|
}
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Hook newbuf in at current. */
|
2004-11-04 13:47:28 +00:00
|
|
|
if (marked_cut != CUT_LINE) {
|
2003-12-24 08:03:54 +00:00
|
|
|
filestruct *hold = current;
|
2002-07-19 01:08:59 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* If there's only one line in the cutbuffer... */
|
2000-06-06 05:53:49 +00:00
|
|
|
if (cutbuffer->next == NULL) {
|
2002-07-19 01:08:59 +00:00
|
|
|
size_t buf_len = strlen(cutbuffer->data);
|
|
|
|
size_t cur_len = strlen(current->data);
|
|
|
|
|
2004-11-04 13:47:28 +00:00
|
|
|
current->data = charealloc(current->data, cur_len +
|
|
|
|
buf_len + 1);
|
2003-09-16 02:04:00 +00:00
|
|
|
charmove(current->data + current_x + buf_len,
|
2004-11-04 13:47:28 +00:00
|
|
|
current->data + current_x, cur_len - current_x + 1);
|
|
|
|
strncpy(current->data + current_x, cutbuffer->data,
|
|
|
|
buf_len);
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Use strncpy() to not copy the null terminator. */
|
2002-07-19 01:08:59 +00:00
|
|
|
|
|
|
|
current_x += buf_len;
|
|
|
|
totsize += buf_len;
|
2000-06-06 05:53:49 +00:00
|
|
|
|
|
|
|
placewewant = xplustabs();
|
2003-12-24 08:03:54 +00:00
|
|
|
} else { /* Yuck -- no kidding! */
|
|
|
|
char *tmpstr, *tmpstr2;
|
|
|
|
|
2000-06-06 05:53:49 +00:00
|
|
|
tmp = current->next;
|
2003-12-24 08:03:54 +00:00
|
|
|
|
|
|
|
/* New beginning. */
|
2001-05-17 11:35:43 +00:00
|
|
|
tmpstr = charalloc(current_x + strlen(newbuf->data) + 1);
|
2000-06-06 05:53:49 +00:00
|
|
|
strncpy(tmpstr, current->data, current_x);
|
|
|
|
strcpy(&tmpstr[current_x], newbuf->data);
|
|
|
|
totsize += strlen(newbuf->data) + strlen(newend->data) + 1;
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* New end. */
|
2001-05-17 11:35:43 +00:00
|
|
|
tmpstr2 = charalloc(strlen(newend->data) +
|
2004-11-04 13:47:28 +00:00
|
|
|
strlen(¤t->data[current_x]) + 1);
|
2000-06-06 05:53:49 +00:00
|
|
|
strcpy(tmpstr2, newend->data);
|
|
|
|
strcat(tmpstr2, ¤t->data[current_x]);
|
|
|
|
|
|
|
|
free(current->data);
|
|
|
|
current->data = tmpstr;
|
|
|
|
current->next = newbuf->next;
|
|
|
|
newbuf->next->prev = current;
|
|
|
|
delete_node(newbuf);
|
|
|
|
|
|
|
|
current_x = strlen(newend->data);
|
|
|
|
placewewant = xplustabs();
|
|
|
|
free(newend->data);
|
|
|
|
newend->data = tmpstr2;
|
|
|
|
|
|
|
|
newend->next = tmp;
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* If tmp isn't NULL, we're in the middle: update the
|
|
|
|
* prev pointer. If it IS NULL, we're at the end; update
|
|
|
|
* the filebot pointer. */
|
2000-06-06 05:53:49 +00:00
|
|
|
if (tmp != NULL)
|
|
|
|
tmp->prev = newend;
|
2000-12-10 05:44:02 +00:00
|
|
|
else {
|
2000-06-06 05:53:49 +00:00
|
|
|
filebot = newend;
|
2000-12-10 05:54:27 +00:00
|
|
|
new_magicline();
|
2000-12-10 05:44:02 +00:00
|
|
|
}
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Now why don't we update the totsize also? */
|
2000-06-06 05:53:49 +00:00
|
|
|
for (tmp = current->next; tmp != newend; tmp = tmp->next)
|
|
|
|
totsize += strlen(tmp->data) + 1;
|
|
|
|
|
|
|
|
current = newend;
|
|
|
|
}
|
|
|
|
|
2004-11-04 13:47:28 +00:00
|
|
|
/* If we're doing a cut to end, we don't want anything else on
|
|
|
|
* the line, so we have to screw up all the work we just did and
|
|
|
|
* separate the line. */
|
|
|
|
if (marked_cut == CUT_TO_END) {
|
2000-07-27 05:09:22 +00:00
|
|
|
tmp = make_new_node(current);
|
2002-12-22 16:30:00 +00:00
|
|
|
tmp->data = mallocstrcpy(NULL, current->data + current_x);
|
2000-07-28 00:58:35 +00:00
|
|
|
splice_node(current, tmp, current->next);
|
2001-10-22 23:22:19 +00:00
|
|
|
null_at(¤t->data, current_x);
|
2000-07-27 13:03:31 +00:00
|
|
|
current = current->next;
|
|
|
|
current_x = 0;
|
|
|
|
placewewant = 0;
|
2001-06-21 15:07:40 +00:00
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Extra line added; update stuff. */
|
2001-06-21 15:07:40 +00:00
|
|
|
totlines++;
|
|
|
|
totsize++;
|
2000-07-27 05:09:22 +00:00
|
|
|
}
|
2000-12-10 05:44:02 +00:00
|
|
|
/* Renumber from BEFORE where we pasted ;) */
|
|
|
|
renumber(hold);
|
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
#ifdef DEBUG
|
2000-06-06 05:53:49 +00:00
|
|
|
dump_buffer(fileage);
|
|
|
|
dump_buffer(cutbuffer);
|
2002-07-19 01:08:59 +00:00
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
set_modified();
|
2003-12-24 08:03:54 +00:00
|
|
|
edit_refresh();
|
2004-07-02 14:31:03 +00:00
|
|
|
return;
|
2002-07-19 01:08:59 +00:00
|
|
|
}
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
if (current != fileage) {
|
|
|
|
tmp = current->prev;
|
2000-06-06 05:53:49 +00:00
|
|
|
tmp->next = newbuf;
|
|
|
|
newbuf->prev = tmp;
|
2002-07-19 01:08:59 +00:00
|
|
|
} else
|
2000-06-06 05:53:49 +00:00
|
|
|
fileage = newbuf;
|
2003-12-24 08:03:54 +00:00
|
|
|
totlines++; /* Unmarked uncuts don't split lines. */
|
2000-06-06 05:53:49 +00:00
|
|
|
|
|
|
|
/* This is so uncutting at the top of the buffer will work => */
|
|
|
|
if (current_y == 0)
|
|
|
|
edittop = newbuf;
|
|
|
|
|
2003-12-24 08:03:54 +00:00
|
|
|
/* Connect the end of the buffer to the filestruct. */
|
|
|
|
newend->next = current;
|
|
|
|
current->prev = newend;
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
/* Recalculate size *sigh* */
|
2003-12-24 08:03:54 +00:00
|
|
|
for (tmp = newbuf; tmp != current; tmp = tmp->next)
|
2000-06-06 05:53:49 +00:00
|
|
|
totsize += strlen(tmp->data) + 1;
|
|
|
|
|
|
|
|
renumber(newbuf);
|
2003-12-24 08:03:54 +00:00
|
|
|
edit_refresh();
|
2000-06-06 05:53:49 +00:00
|
|
|
|
2002-07-19 01:08:59 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
dump_buffer_reverse();
|
|
|
|
#endif
|
2000-06-06 05:53:49 +00:00
|
|
|
|
|
|
|
set_modified();
|
|
|
|
}
|