nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] cutting: copy anchors into the cutbuffer, so that undo can resto


From: Benno Schulenberg
Subject: [PATCH] cutting: copy anchors into the cutbuffer, so that undo can restore them
Date: Wed, 15 Sep 2021 17:08:49 +0200

This addresses https://savannah.gnu.org/bugs/?61162 and far more.
---
 src/cut.c         | 17 ++++++++++++++++-
 src/definitions.h |  1 +
 src/nano.c        |  2 +-
 src/text.c        |  7 +++++++
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/cut.c b/src/cut.c
index 6793798b..925dd906 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -249,6 +249,7 @@ void extract_segment(linestruct *top, size_t top_x, 
linestruct *bot, size_t bot_
        bool same_line = (openfile->mark == top);
        bool post_marked = (openfile->mark && (openfile->mark->lineno > 
top->lineno ||
                                                (same_line && openfile->mark_x 
> top_x)));
+       static bool inherited_anchor = FALSE;
        bool was_anchored = top->has_anchor;
 
        if (top == bot && top_x == bot_x)
@@ -309,11 +310,17 @@ void extract_segment(linestruct *top, size_t top_x, 
linestruct *bot, size_t bot_
        if (cutbuffer == NULL) {
                cutbuffer = taken;
                cutbottom = last;
+#ifndef NANO_TINY
+               inherited_anchor = taken->has_anchor;
+#endif
        } else {
                cutbottom->data = nrealloc(cutbottom->data,
                                                        strlen(cutbottom->data) 
+ strlen(taken->data) + 1);
                strcat(cutbottom->data, taken->data);
-
+#ifndef NANO_TINY
+               cutbottom->has_anchor = taken->has_anchor && !inherited_anchor;
+               inherited_anchor |= taken->has_anchor;
+#endif
                cutbottom->next = taken->next;
                delete_node(taken);
 
@@ -686,6 +693,9 @@ void copy_text(void)
 /* Copy text from the cutbuffer into the current buffer. */
 void paste_text(void)
 {
+       /* Remember where the paste started. */
+       linestruct *was_current = openfile->current;
+       bool had_anchor = was_current->has_anchor;
        ssize_t was_lineno = openfile->current->lineno;
                /* The line number where we started the paste. */
        size_t was_leftedge = 0;
@@ -708,6 +718,11 @@ void paste_text(void)
        copy_from_buffer(cutbuffer);
 
 #ifndef NANO_TINY
+       for (linestruct *line = was_current; line != openfile->current->next; 
line = line->next)
+               line->has_anchor = FALSE;
+
+       was_current->has_anchor = had_anchor;
+
        update_undo(PASTE);
 #endif
 
diff --git a/src/definitions.h b/src/definitions.h
index 9a9c8550..cb864a7d 100644
--- a/src/definitions.h
+++ b/src/definitions.h
@@ -220,6 +220,7 @@
 #define INCLUDED_LAST_LINE    (1<<3)
 #define MARK_WAS_SET          (1<<4)
 #define CURSOR_WAS_AT_HEAD    (1<<5)
+#define HAD_ANCHOR_AT_START   (1<<6)
 #endif /* !NANO_TINY */
 
 /* Identifiers for the different menus. */
diff --git a/src/nano.c b/src/nano.c
index 3dd9f917..40409784 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -154,7 +154,7 @@ linestruct *copy_node(const linestruct *src)
 #endif
        dst->lineno = src->lineno;
 #ifndef NANO_TINY
-       dst->has_anchor = FALSE;
+       dst->has_anchor = src->has_anchor;
 #endif
 
        return dst;
diff --git a/src/text.c b/src/text.c
index e374fb58..14483de0 100644
--- a/src/text.c
+++ b/src/text.c
@@ -463,6 +463,9 @@ void undo_cut(undostruct *u)
 {
        goto_line_posx(u->head_lineno, (u->xflags & WAS_WHOLE_LINE) ? 0 : 
u->head_x);
 
+       if (!(u->xflags & HAD_ANCHOR_AT_START))
+               openfile->current->has_anchor = FALSE;
+
        if (u->cutbuffer)
                copy_from_buffer(u->cutbuffer);
 
@@ -1044,6 +1047,10 @@ void add_undo(undo_type action, const char *message)
                        u->tail_x = 0;
                } else
                        u->xflags |= CURSOR_WAS_AT_HEAD;
+
+               if ((openfile->mark && mark_is_before_cursor() && 
openfile->mark->has_anchor) ||
+                               ((!openfile->mark || !mark_is_before_cursor()) 
&& openfile->current->has_anchor))
+                       u->xflags |= HAD_ANCHOR_AT_START;
                break;
        case PASTE:
                u->cutbuffer = copy_buffer(cutbuffer);
-- 
2.29.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]