From e1e0fd634b99086f1ba1cb67d1ca27a60b24f663 Mon Sep 17 00:00:00 2001
From: Chris Allegretta <chrisa@asty.org>
Date: Tue, 15 Apr 2003 01:15:09 +0000
Subject: [PATCH] DLR and DB's latest fixes

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1489 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog | 33 +++++++++++++++++++++++
 cut.c     | 51 ++++++++++++++++++++++++++----------
 files.c   |  2 --
 global.c  |  1 +
 move.c    |  8 ------
 nano.c    | 78 +++++++++++++++++++++++++++++++------------------------
 proto.h   |  2 +-
 search.c  | 14 +++-------
 utils.c   |  2 +-
 winio.c   |  2 +-
 10 files changed, 123 insertions(+), 70 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ce88a319..15ba5559 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,28 @@ CVS code -
 	  if ~/.nano_history is unwritable, and prevent ~/.nano_history
 	  from being completely overwritten by save_history() if it's
 	  unreadable but writable. (David Benbennick)
+	- Only unset KEEP_CUTBUFFER in main() when we do something other
+	  than cut text in the main input loop, instead of unsetting it
+	  all over the place (which, as written, didn't handle cases
+	  like a cut followed by M-Space properly).  Also, instead of
+	  checking for keyhandled's not being set inside the for loops,
+	  do it in if blocks surrounding the for loops to increase
+	  efficiency. (David Benbennick)  DLR: Also unset KEEP_CUTBUFFER
+	  if we hit a shortcut key other than the one for cutting text.
+	- Make it so a marked cut immediately followed by an unmarked
+	  cut tacks the latter's text onto the end of the former's text
+	  instead of putting it on a new line, as Pico does. (DLR)
+	- Convert instances of "(char *)nrealloc()" to the macro
+	  charealloc(), which does the same thing. (DLR)
+- cut.c:
+  do_cut_text()
+	- Tweak where KEEP_CUTBUFFER is set so that a marked cut
+	  immediately followed by an unmarked cut preserves the
+	  cutbuffer between the two. (David Benbennick)  DLR: Also
+	  properly set KEEP_CUTBUFFER in tiny mode.
+  do_uncut_text()
+	- If we're about to uncut on the magicline, always make a new
+	  magicline in advance, as Pico does. (DLR)
 - global.c:
   shortcut_init()
 	- Simplify the #ifdef used to enable file insertion in view mode
@@ -22,6 +44,17 @@ CVS code -
 - nano.h:
 	- Simplify #ifdefs relating to HAVE_STRCASECMP and
 	  HAVE_STRNCASECMP. (David Benbennick)
+- search.c:
+  goto_abort()
+	- Removed, with all instances replaced with display_main_list(),
+	  since with the removal of all the scattered calls to
+	  SET(KEEP_CUTBUFFER), that function was all that was left of
+	  it. (DLR)
+  do_find_bracket()
+	- If a matching bracket wasn't found, call update_line() after
+	  setting current and current_x back to their original values,
+	  in case current_x's original value is greater than the width
+	  of the screen. (DLR)
 - configure.ac:
 	- Enable autodetection of broken regexec(). (DLR) Re-added 
 	  regex.h check to ensure compile under Debian w/autoconf 1.6.
diff --git a/cut.c b/cut.c
index cf692a2c..ebcb7c87 100644
--- a/cut.c
+++ b/cut.c
@@ -29,6 +29,12 @@
 #include "nano.h"
 
 static int marked_cut;		/* Is the cutbuffer from a mark? */
+
+#ifndef NANO_SMALL
+static int concatenate_cut;	/* Should we add this cut string to the
+				   end of the last one? */
+#endif
+
 static filestruct *cutbottom = NULL;
 				/* Pointer to end of cutbuffer */
 
@@ -47,6 +53,15 @@ void add_to_cutbuffer(filestruct *inptr)
     if (cutbuffer == NULL) {
 	cutbuffer = inptr;
 	inptr->prev = NULL;
+#ifndef NANO_SMALL
+    } else if (concatenate_cut && !justify_mode) {
+	/* Just tack the text in inptr onto the text in cutbottom,
+	   unless we're backing up lines while justifying text. */
+	cutbottom->data = charealloc(cutbottom->data,
+		strlen(cutbottom->data) + strlen(inptr->data) + 1);
+	strcat(cutbottom->data, inptr->data);
+	return;
+#endif
     } else {
 	cutbottom->next = inptr;
 	inptr->prev = cutbottom;
@@ -118,15 +133,13 @@ void cut_marked_segment(filestruct *top, size_t top_x, filestruct *bot,
 	       move text from the end forward first. */
 	    memmove(top->data + top_x, bot->data + bot_x,
 			newsize - top_x);
-	    top->data = (char *)nrealloc(top->data,
-					sizeof(char) * newsize);
+	    top->data = charealloc(top->data, newsize);
 	} else {
 	    totsize -= bot_x + 1;
 
 	    /* Here, the remainder line might get longer, so we
 	       realloc() it first. */
-	    top->data = (char *)nrealloc(top->data,
-					sizeof(char) * newsize);
+	    top->data = charealloc(top->data, newsize);
 	    memmove(top->data + top_x, bot->data + bot_x,
 			newsize - top_x);
 	}
@@ -172,6 +185,9 @@ void cut_marked_segment(filestruct *top, size_t top_x, filestruct *bot,
 		new_magicline();
 	}
     }
+#ifdef DEBUG
+    dump_buffer(cutbuffer);
+#endif
 }
 #endif
 
@@ -190,6 +206,9 @@ int do_cut_text(void)
 	free_filestruct(cutbuffer);
 	cutbuffer = NULL;
 	marked_cut = 0;
+#ifndef NANO_SMALL
+	concatenate_cut = 0;
+#endif
 #ifdef DEBUG
 	fprintf(stderr, _("Blew away cutbuffer =)\n"));
 #endif
@@ -204,6 +223,8 @@ int do_cut_text(void)
 						)
 	return 0;
 
+    SET(KEEP_CUTBUFFER);
+
 #ifndef NANO_SMALL
     if (ISSET(CUT_TO_END) && !ISSET(MARK_ISSET)) {
 	assert(current_x >= 0 && current_x <= strlen(current->data));
@@ -223,12 +244,10 @@ int do_cut_text(void)
 	    }
 
 	    do_delete();
-	    SET(KEEP_CUTBUFFER);
 	    marked_cut = 2;
 	    return 1;
 	} else {
 	    SET(MARK_ISSET);
-	    SET(KEEP_CUTBUFFER);
 
 	    mark_beginx = strlen(current->data);
 	    mark_beginbuf = current;
@@ -249,6 +268,11 @@ int do_cut_text(void)
 	placewewant = xplustabs();
 	UNSET(MARK_ISSET);
 
+	/* If we just did a marked cut of part of a line, we should add
+	   the first line of any cut done immediately afterward to the
+	   end of this cut, as Pico does. */
+	if (current == mark_beginbuf && current_x < strlen(current->data))
+	    concatenate_cut = 1;
 	marked_cut = 1;
 	if (dontupdate)
 	    edit_refresh();
@@ -283,8 +307,10 @@ int do_cut_text(void)
     edit_refresh();
     set_modified();
     marked_cut = 0;
+#ifndef NANO_SMALL
+    concatenate_cut = 0;
+#endif
     placewewant = 0;
-    SET(KEEP_CUTBUFFER);
     return 1;
 }
 
@@ -312,6 +338,11 @@ int do_uncut_text(void)
 	    placewewant = 0;
     }
 
+    /* If we're going to uncut on the magicline, always make a new
+       magicline in advance. */
+    if (current->next == NULL)
+	new_magicline();
+
     if (marked_cut == 0 || cutbuffer->next != NULL)
     {
 	newbuf = copy_filestruct(cutbuffer);
@@ -338,10 +369,6 @@ int do_uncut_text(void)
 
 	    current_x += buf_len;
 	    totsize += buf_len;
-	    /* If we've uncut a line, make sure there's a magicline after
-	       it */
-	    if (current->next == NULL)
-		new_magicline();
 
 	    placewewant = xplustabs();
 	    update_cursor();
@@ -426,7 +453,6 @@ int do_uncut_text(void)
 	    edit_update(current, CENTER);
 	else
 	    edit_refresh();
-	UNSET(KEEP_CUTBUFFER);
 	return 0;
     }
 
@@ -464,6 +490,5 @@ int do_uncut_text(void)
 #endif
 
     set_modified();
-    UNSET(KEEP_CUTBUFFER);
     return 1;
 }
diff --git a/files.c b/files.c
index db825008..1d88bed0 100644
--- a/files.c
+++ b/files.c
@@ -495,7 +495,6 @@ int do_insertfile(int loading_file)
 		_("Command to execute"));
 	    if (ts  == -1 || answer == NULL || answer[0] == '\0') {
 		statusbar(_("Cancelled"));
-		UNSET(KEEP_CUTBUFFER);
 		display_main_list();
 		return 0;
 	    }
@@ -618,7 +617,6 @@ int do_insertfile(int loading_file)
     free(inspath);
     inspath = NULL;
 
-    UNSET(KEEP_CUTBUFFER);
     display_main_list();
     return i;
 }
diff --git a/global.c b/global.c
index 0173cd8b..ef8ac508 100644
--- a/global.c
+++ b/global.c
@@ -65,6 +65,7 @@ openfilestruct *open_files = NULL;	/* The list of open files */
 #endif
 
 #ifndef DISABLE_JUSTIFY
+int justify_mode = 0;		/* Whether we're justifying now. */
 char *quotestr = NULL;		/* Quote string.  The default value is
 				   set in main(). */
 #endif
diff --git a/move.c b/move.c
index 3baf14b2..994d9cb7 100644
--- a/move.c
+++ b/move.c
@@ -30,7 +30,6 @@
 
 int do_home(void)
 {
-    UNSET(KEEP_CUTBUFFER);
     current_x = 0;
     placewewant = 0;
     update_line(current, current_x);
@@ -39,7 +38,6 @@ int do_home(void)
 
 int do_end(void)
 {
-    UNSET(KEEP_CUTBUFFER);
     current_x = strlen(current->data);
     placewewant = xplustabs();
     update_line(current, current_x);
@@ -89,7 +87,6 @@ int do_page_up(void)
     edit_update(current, TOP);
     update_cursor();
 
-    UNSET(KEEP_CUTBUFFER);
     check_statblank();
     return 1;
 }
@@ -132,7 +129,6 @@ int do_page_down(void)
     }
 
     update_cursor();
-    UNSET(KEEP_CUTBUFFER);
     check_statblank();
     return 1;
 }
@@ -151,7 +147,6 @@ int do_up(void)
 	    update_line(current, current_x);
 	} else
 	    page_up();
-	UNSET(KEEP_CUTBUFFER);
 	check_statblank();
     }
     return 1;
@@ -162,7 +157,6 @@ int do_up(void)
 int do_down(void)
 {
     wrap_reset();
-    UNSET(KEEP_CUTBUFFER);
     check_statblank();
 
     if (current->next == NULL)
@@ -207,7 +201,6 @@ int do_left(void)
     }
     placewewant = xplustabs();
     update_line(current, current_x);
-    UNSET(KEEP_CUTBUFFER);
     check_statblank();
     return 1;
 }
@@ -224,7 +217,6 @@ int do_right(void)
     }
     placewewant = xplustabs();
     update_line(current, current_x);
-    UNSET(KEEP_CUTBUFFER);
     check_statblank();
     return 1;
 }
diff --git a/nano.c b/nano.c
index 9ab79b1e..57807e95 100644
--- a/nano.c
+++ b/nano.c
@@ -1018,8 +1018,6 @@ void do_char(char ch)
     if (refresh)
 	edit_refresh();
 #endif
-
-    UNSET(KEEP_CUTBUFFER);
 }
 
 int do_backspace(void)
@@ -1093,7 +1091,6 @@ int do_backspace(void)
 #ifdef DEBUG
 	fprintf(stderr, _("After, data = \"%s\"\n"), current->data);
 #endif
-	UNSET(KEEP_CUTBUFFER);
 	refresh = 1;
     }
 
@@ -1152,7 +1149,6 @@ int do_delete(void)
 
     totsize--;
     set_modified();
-    UNSET(KEEP_CUTBUFFER);
     update_line(current, current_x);
     if (refresh)
 	edit_refresh();
@@ -2428,6 +2424,7 @@ int do_justify(void)
 
 /* Next step, we loop through the lines of this paragraph, justifying
  * each one individually. */
+    justify_mode = 1;
     for(; par_len > 0; current_y++, par_len--) {
 	size_t line_len;
 	size_t display_len;
@@ -2491,9 +2488,8 @@ int do_justify(void)
 
 		indent_len = quote_len +
 			indent_length(current->next->data + quote_len);
-		current->next->data = (char *)nrealloc(current->next->data,
-			sizeof(char) * (next_line_len + line_len -
-					break_pos + 1));
+		current->next->data = charealloc(current->next->data,
+			next_line_len + line_len - break_pos + 1);
 
 		memmove(current->next->data + indent_len + line_len - break_pos,
 			current->next->data + indent_len,
@@ -2537,7 +2533,7 @@ int do_justify(void)
 				fill - display_len - 1, FALSE);
 	    assert(break_pos != -1);
 
-	    current->data = (char *)nrealloc(current->data,
+	    current->data = charealloc(current->data,
 					line_len + break_pos + 2);
 	    current->data[line_len] = ' ';
 	    strncpy(current->data + line_len + 1,
@@ -2580,6 +2576,8 @@ int do_justify(void)
   continue_loc:
 	    current = current->next;
     }
+    justify_mode = 0;
+
 /* We are now done justifying the paragraph.  There are cleanup things to
  * do, and we check for unjustify. */
 
@@ -2664,10 +2662,9 @@ int do_justify(void)
 	}
 	edit_refresh();
     }
-    UNSET(KEEP_CUTBUFFER);
     cutbuffer = cutbuffer_save;
     blank_statusbar_refresh();
-    /* display shortcut list without UnCut */
+    /* display shortcut list with UnCut */
     shortcut_init(0);
     display_main_list();
 
@@ -3632,20 +3629,25 @@ int main(int argc, char *argv[])
 			    kbinput <= 'Z' && kbinput == s->altval - 32)) {
 			if (ISSET(VIEW_MODE) && !s->viewok)
 			    print_view_warning();
-			else
+			else {
+			    if (s->func != do_cut_text)
+				UNSET(KEEP_CUTBUFFER);
 			    s->func();
+			}
 			keyhandled = 1;
 			break;
 		    }
 #ifndef NANO_SMALL
-		/* And for toggle switches */
-		for (t = toggles; t != NULL && !keyhandled; t = t->next)
-		    if (kbinput == t->val || (t->val >= 'a' &&
-			    t->val <= 'z' && kbinput == t->val - 32)) {
-			do_toggle(t);
-			keyhandled = 1;
-			break;
-		    }
+		if (!keyhandled)
+		    /* And for toggle switches */
+		    for (t = toggles; t != NULL; t = t->next)
+			if (kbinput == t->val || (t->val >= 'a' &&
+				t->val <= 'z' && kbinput == t->val - 32)) {
+			    UNSET(KEEP_CUTBUFFER);
+			    do_toggle(t);
+			    keyhandled = 1;
+			    break;
+		        }
 #endif
 #ifdef DEBUG
 		fprintf(stderr, _("I got Alt-%c! (%d)\n"), kbinput,
@@ -3675,25 +3677,33 @@ int main(int argc, char *argv[])
 	/* Look through the main shortcut list to see if we've hit a
 	   shortcut key */
 
+	if (!keyhandled)
 #if !defined(DISABLE_BROWSER) || !defined (DISABLE_HELP) || (!defined(DISABLE_MOUSE) && defined(NCURSES_MOUSE_VERSION))
-	for (s = currshortcut; s != NULL && !keyhandled; s = s->next) {
+	    for (s = currshortcut; s != NULL && !keyhandled; s = s->next) {
 #else
-	for (s = main_list; s != NULL && !keyhandled; s = s->next) {
+	    for (s = main_list; s != NULL && !keyhandled; s = s->next) {
 #endif
-	    if (kbinput == s->val ||
-		(s->misc1 && kbinput == s->misc1) ||
-		(s->misc2 && kbinput == s->misc2)) {
-		if (ISSET(VIEW_MODE) && !s->viewok)
-		    print_view_warning();
-		else
-		    s->func();
-		keyhandled = 1;
-		/* Rarely, the value of s can change after s->func(),
-		   leading to problems; get around this by breaking out
-		   explicitly once we successfully handle a shortcut */
-		break;
+		if (kbinput == s->val ||
+		    (s->misc1 && kbinput == s->misc1) ||
+		    (s->misc2 && kbinput == s->misc2)) {
+		    if (ISSET(VIEW_MODE) && !s->viewok)
+			print_view_warning();
+		    else {
+			if (s->func != do_cut_text)
+			    UNSET(KEEP_CUTBUFFER);
+			s->func();
+		    }
+		    keyhandled = 1;
+		    /* Rarely, the value of s can change after
+		       s->func(), leading to problems; get around this
+		       by breaking out explicitly once we successfully
+		       handle a shortcut */
+		    break;
+		}
 	    }
-	}
+
+	if (!keyhandled)
+	    UNSET(KEEP_CUTBUFFER);
 
 #ifdef _POSIX_VDISABLE
 	/* Don't even think about changing this string */
diff --git a/proto.h b/proto.h
index bc9015a4..59891377 100644
--- a/proto.h
+++ b/proto.h
@@ -44,6 +44,7 @@ extern int search_offscreen;
 extern int currslen;
 
 #ifndef DISABLE_JUSTIFY
+extern int justify_mode;
 extern char *quotestr;
 #endif
 
@@ -367,7 +368,6 @@ char *replace_line(void);
 int do_replace_loop(const char *prevanswer, const filestruct *begin,
 			int *beginx, int wholewords, int *i);
 int do_replace(void);
-void goto_abort(void);
 int do_gotoline(int line, int save_pos);
 int do_gotoline_void(void);
 #if defined (ENABLE_MULTIBUFFER) || !defined (DISABLE_SPELLER)
diff --git a/search.c b/search.c
index ebf3fe8b..7304d1a7 100644
--- a/search.c
+++ b/search.c
@@ -67,7 +67,6 @@ void not_found_msg(const char *str)
 
 void search_abort(void)
 {
-    UNSET(KEEP_CUTBUFFER);
     display_main_list();
     wrefresh(bottomwin);
     if (ISSET(MARK_ISSET))
@@ -768,12 +767,6 @@ int do_replace(void)
     return 1;
 }
 
-void goto_abort(void)
-{
-    UNSET(KEEP_CUTBUFFER);
-    display_main_list();
-}
-
 int do_gotoline(int line, int save_pos)
 {
     if (line <= 0) {		/* Ask for it */
@@ -787,7 +780,7 @@ int do_gotoline(int line, int save_pos)
 	if (st == -1 || st == -2)
 	    statusbar(_("Aborted"));
 	if (st != 0) {
-	    goto_abort();
+	    display_main_list();
 	    return 0;
 	}
 
@@ -796,7 +789,7 @@ int do_gotoline(int line, int save_pos)
 	/* Bounds check */
 	if (line <= 0) {
 	    statusbar(_("Come on, be reasonable"));
-	    goto_abort();
+	    display_main_list();
 	    return 0;
 	}
     }
@@ -813,7 +806,7 @@ int do_gotoline(int line, int save_pos)
     else
 	edit_update(current, CENTER);
     placewewant = 0;
-    goto_abort();
+    display_main_list();
     return 1;
 }
 
@@ -909,6 +902,7 @@ int do_find_bracket(void)
 	    statusbar(_("No matching bracket"));
 	    current_x = current_x_save;
 	    current = current_save;
+	    update_line(current, current_x);
 	    break;
 	}
     }
diff --git a/utils.c b/utils.c
index 261c03a2..452e1506 100644
--- a/utils.c
+++ b/utils.c
@@ -74,7 +74,7 @@ void align(char **strp)
 void null_at(char **data, size_t index)
 {
     assert(data != NULL);
-    *data = (char *)nrealloc(*data, sizeof(char) * (index + 1));
+    *data = charealloc(*data, index + 1);
     (*data)[index] = '\0';
 }
 
diff --git a/winio.c b/winio.c
index 8a1051ee..1731eabf 100644
--- a/winio.c
+++ b/winio.c
@@ -221,7 +221,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
     if (x == -1 || x > xend || resetstatuspos)
 	x = xend;
 
-    answer = (char *)nrealloc(answer, xend + 1);
+    answer = charealloc(answer, xend + 1);
     if (xend > 0)
 	strcpy(answer, def);
     else
-- 
GitLab