Benno Schulenberg
2018-10-28 13:41:01 UTC
From: Brand Huntsman <***@qzx.com>
Signed-off-by: Brand Huntsman <***@qzx.com>
---
doc/nano.texi | 3 +++
doc/nanorc.5 | 3 +++
src/cut.c | 41 ++++++++++++++++++++++++++++++++++-------
src/files.c | 4 ++--
src/global.c | 8 ++++++++
src/nano.h | 2 +-
src/proto.h | 3 ++-
src/text.c | 24 +++++++++++++++++++-----
8 files changed, 72 insertions(+), 16 deletions(-)
diff --git a/doc/nano.texi b/doc/nano.texi
index a643ec80..13495249 100644
--- a/doc/nano.texi
+++ b/doc/nano.texi
@@ -1150,6 +1150,9 @@ Pastes the currently stored text into the current buffer at the
current cursor position.
(The old form 'uncut' is deprecated.)
+@item zap
+Throw away the current line (or the marked region).
+
@item cutwordleft
Cuts from the cursor position to the beginning of the preceding word.
(This function is not bound by default. If your terminal produces
diff --git a/doc/nanorc.5 b/doc/nanorc.5
index 96e49df6..a40bcf0a 100644
--- a/doc/nanorc.5
+++ b/doc/nanorc.5
@@ -506,6 +506,9 @@ Pastes the currently stored text into the current buffer at the
current cursor position.
(The old form 'uncut' is deprecated.)
.TP
+.B zap
+Throw away the current line (or the marked region).
+.TP
.B cutwordleft
Cuts from the cursor position to the beginning of the preceding word.
(This function is not bound by default. If your terminal produces
diff --git a/src/cut.c b/src/cut.c
index 69c50062..0f33e1d4 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -104,8 +104,9 @@ void cut_to_eof(void)
/* Move text from the current buffer into the cutbuffer. If
* copy_text is TRUE, copy the text back into the buffer afterward.
* If cut_till_eof is TRUE, move all text from the current cursor
- * position to the end of the file into the cutbuffer. */
-void do_cut_text(bool copy_text, bool marked, bool cut_till_eof)
+ * position to the end of the file into the cutbuffer. If append
+ * is TRUE (when zapping), always append the cut to the cutbuffer. */
+void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append)
{
#ifndef NANO_TINY
filestruct *cb_save = NULL;
@@ -120,7 +121,7 @@ void do_cut_text(bool copy_text, bool marked, bool cut_till_eof)
size_t was_totsize = openfile->totsize;
/* If cuts were not continuous, or when cutting a region, clear the slate. */
- if (!keep_cutbuffer || marked || cut_till_eof) {
+ if (!append && (!keep_cutbuffer || marked || cut_till_eof)) {
free_filestruct(cutbuffer);
cutbuffer = NULL;
/* After a line cut, future line cuts should add to the cutbuffer. */
@@ -193,10 +194,10 @@ void do_cut_text_void(void)
openfile->current_undo->mark_begin_lineno != openfile->current->lineno ||
!keep_cutbuffer)
add_undo(CUT);
- do_cut_text(FALSE, openfile->mark, FALSE);
+ do_cut_text(FALSE, openfile->mark, FALSE, FALSE);
update_undo(CUT);
#else
- do_cut_text(FALSE, FALSE, FALSE);
+ do_cut_text(FALSE, FALSE, FALSE, FALSE);
#endif
}
@@ -218,7 +219,7 @@ void do_copy_text(void)
if (mark_is_set || openfile->current != next_contiguous_line)
cutbuffer_reset();
- do_cut_text(TRUE, mark_is_set, FALSE);
+ do_cut_text(TRUE, mark_is_set, FALSE, FALSE);
/* If the mark was set, blow away the cutbuffer on the next copy. */
next_contiguous_line = (mark_is_set ? NULL : openfile->current);
@@ -236,9 +237,35 @@ void do_copy_text(void)
void do_cut_till_eof(void)
{
add_undo(CUT_TO_EOF);
- do_cut_text(FALSE, FALSE, TRUE);
+ do_cut_text(FALSE, FALSE, TRUE, FALSE);
update_undo(CUT_TO_EOF);
}
+
+/* Erase text (current line or marked region), sending it into oblivion. */
+void zap_text(void)
+{
+ /* Remember the current cutbuffer so it can be restored after the zap. */
+ filestruct *was_cutbuffer = cutbuffer;
+ filestruct *was_cutbottom = cutbottom;
+
+ /* Add a new undo item only when the current item is not a ZAP or when
+ * the current zap is not contiguous with the previous zapping. */
+ if (openfile->last_action != ZAP || openfile->current_undo == NULL ||
+ openfile->current_undo->mark_begin_lineno != openfile->current->lineno ||
+ openfile->current_undo->xflags & (MARK_WAS_SET|WAS_MARKED_FORWARD))
+ add_undo(ZAP);
+
+ /* Use the cutbuffer from the ZAP undo item, so the cut can be undone. */
+ cutbuffer = openfile->current_undo->cutbuffer;
+ cutbottom = openfile->current_undo->cutbottom;
+
+ do_cut_text(FALSE, openfile->mark, FALSE, TRUE);
+
+ update_undo(ZAP);
+
+ cutbuffer = was_cutbuffer;
+ cutbottom = was_cutbottom;
+}
#endif /* !NANO_TINY */
/* Copy text from the cutbuffer into the current buffer. */
diff --git a/src/files.c b/src/files.c
index 5878ff00..4b757c65 100644
--- a/src/files.c
+++ b/src/files.c
@@ -533,7 +533,7 @@ void replace_buffer(const char *filename)
#ifndef NANO_TINY
add_undo(CUT_TO_EOF);
#endif
- do_cut_text(FALSE, FALSE, TRUE);
+ do_cut_text(FALSE, FALSE, TRUE, FALSE);
#ifndef NANO_TINY
update_undo(CUT_TO_EOF);
#endif
@@ -574,7 +574,7 @@ void replace_marked_buffer(const char *filename)
/* Throw away the text under the mark. */
cutbuffer = NULL;
add_undo(CUT);
- do_cut_text(FALSE, TRUE, FALSE);
+ do_cut_text(FALSE, TRUE, FALSE, FALSE);
update_undo(CUT);
free_filestruct(cutbuffer);
cutbuffer = was_cutbuffer;
diff --git a/src/global.c b/src/global.c
index e1d7930f..89df838b 100644
--- a/src/global.c
+++ b/src/global.c
@@ -576,6 +576,7 @@ void shortcut_init(void)
const char *mark_gist = N_("Mark text starting from the cursor position");
const char *copy_gist =
N_("Copy current line (or marked region) and store it in cutbuffer");
+ const char *zap_gist = N_("Throw away the current line (or marked region)");
const char *indent_gist = N_("Indent the current line (or marked lines)");
const char *unindent_gist = N_("Unindent the current line (or marked lines)");
const char *undo_gist = N_("Undo the last operation");
@@ -997,6 +998,11 @@ void shortcut_init(void)
N_("Save"), WITHORSANS(savefile_gist), BLANKAFTER, NOVIEW);
#endif
+#ifndef NANO_TINY
+ add_to_funcs(zap_text, MMAIN,
+ N_("Zap Text"), WITHORSANS(zap_gist), BLANKAFTER, NOVIEW);
+#endif
+
#ifndef ENABLE_JUSTIFY
add_to_funcs(flip_goto, MWHEREIS,
N_("Go To Line"), WITHORSANS(gotoline_gist), BLANKAFTER, VIEW);
@@ -1471,6 +1477,8 @@ sc *strtosc(const char *input)
else if (!strcasecmp(input, "copy") ||
!strcasecmp(input, "copytext")) /* Deprecated. Remove end of 2018. */
s->func = do_copy_text;
+ else if (!strcasecmp(input, "zap"))
+ s->func = zap_text;
else if (!strcasecmp(input, "mark"))
s->func = do_mark;
#endif
diff --git a/src/nano.h b/src/nano.h
index 3007881d..50937695 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -178,7 +178,7 @@ typedef enum {
#ifdef ENABLE_COMMENT
COMMENT, UNCOMMENT, PREFLIGHT,
#endif
- CUT, CUT_TO_EOF, PASTE, INSERT, COUPLE_BEGIN, COUPLE_END, OTHER
+ ZAP, CUT, CUT_TO_EOF, PASTE, INSERT, COUPLE_BEGIN, COUPLE_END, OTHER
} undo_type;
/* Structure types. */
diff --git a/src/proto.h b/src/proto.h
index a157ece0..a2834606 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -249,11 +249,12 @@ void cutbuffer_reset(void);
#ifndef NANO_TINY
void cut_marked(bool *right_side_up);
#endif
-void do_cut_text(bool copy_text, bool marked, bool cut_till_eof);
+void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append);
void do_cut_text_void(void);
#ifndef NANO_TINY
void do_copy_text(void);
void do_cut_till_eof(void);
+void zap_text(void);
#endif
void do_uncut_text(void);
diff --git a/src/text.c b/src/text.c
index 8302c7dd..c9fb4868 100644
--- a/src/text.c
+++ b/src/text.c
@@ -687,7 +687,7 @@ void redo_cut(undo *u)
openfile->mark = fsfromline(u->mark_begin_lineno);
openfile->mark_x = (u->xflags == WAS_WHOLE_LINE) ? 0 : u->mark_begin_x;
- do_cut_text(FALSE, TRUE, FALSE);
+ do_cut_text(FALSE, TRUE, FALSE, u->type == ZAP);
free_filestruct(cutbuffer);
cutbuffer = oldcutbuffer;
@@ -792,6 +792,10 @@ void do_undo(void)
undidmsg = _("text add");
break;
#endif
+ case ZAP:
+ undidmsg = _("erasure");
+ undo_cut(u);
+ break;
case CUT_TO_EOF:
case CUT:
undidmsg = _("text cut");
@@ -968,6 +972,10 @@ void do_redo(void)
redidmsg = _("text add");
break;
#endif
+ case ZAP:
+ redidmsg = _("erasure");
+ redo_cut(u);
+ break;
case CUT_TO_EOF:
case CUT:
redidmsg = _("text cut");
@@ -1201,7 +1209,7 @@ bool execute_command(const char *command)
if (ISSET(MULTIBUFFER)) {
switch_to_prev_buffer();
if (openfile->mark)
- do_cut_text(TRUE, TRUE, FALSE);
+ do_cut_text(TRUE, TRUE, FALSE, FALSE);
} else
#endif
{
@@ -1212,7 +1220,7 @@ bool execute_command(const char *command)
openfile->current_x = 0;
}
add_undo(CUT);
- do_cut_text(FALSE, openfile->mark, openfile->mark == NULL);
+ do_cut_text(FALSE, openfile->mark, openfile->mark == NULL, FALSE);
update_undo(CUT);
}
@@ -1403,6 +1411,7 @@ void add_undo(undo_type action)
#endif
case CUT_TO_EOF:
break;
+ case ZAP:
case CUT:
if (openfile->mark) {
u->mark_begin_lineno = openfile->mark->lineno;
@@ -1529,12 +1538,17 @@ void update_undo(undo_type action)
case SPLIT_END:
break;
#endif
+ case ZAP:
case CUT_TO_EOF:
case CUT:
if (!cutbuffer)
break;
- free_filestruct(u->cutbuffer);
- u->cutbuffer = copy_filestruct(cutbuffer);
+ if (u->type == ZAP)
+ u->cutbuffer = cutbuffer;
+ else {
+ free_filestruct(u->cutbuffer);
+ u->cutbuffer = copy_filestruct(cutbuffer);
+ }
if (u->xflags == MARK_WAS_SET) {
/* If the "marking" operation was from right-->left or
* bottom-->top, then swap the mark points. */
Signed-off-by: Brand Huntsman <***@qzx.com>
---
doc/nano.texi | 3 +++
doc/nanorc.5 | 3 +++
src/cut.c | 41 ++++++++++++++++++++++++++++++++++-------
src/files.c | 4 ++--
src/global.c | 8 ++++++++
src/nano.h | 2 +-
src/proto.h | 3 ++-
src/text.c | 24 +++++++++++++++++++-----
8 files changed, 72 insertions(+), 16 deletions(-)
diff --git a/doc/nano.texi b/doc/nano.texi
index a643ec80..13495249 100644
--- a/doc/nano.texi
+++ b/doc/nano.texi
@@ -1150,6 +1150,9 @@ Pastes the currently stored text into the current buffer at the
current cursor position.
(The old form 'uncut' is deprecated.)
+@item zap
+Throw away the current line (or the marked region).
+
@item cutwordleft
Cuts from the cursor position to the beginning of the preceding word.
(This function is not bound by default. If your terminal produces
diff --git a/doc/nanorc.5 b/doc/nanorc.5
index 96e49df6..a40bcf0a 100644
--- a/doc/nanorc.5
+++ b/doc/nanorc.5
@@ -506,6 +506,9 @@ Pastes the currently stored text into the current buffer at the
current cursor position.
(The old form 'uncut' is deprecated.)
.TP
+.B zap
+Throw away the current line (or the marked region).
+.TP
.B cutwordleft
Cuts from the cursor position to the beginning of the preceding word.
(This function is not bound by default. If your terminal produces
diff --git a/src/cut.c b/src/cut.c
index 69c50062..0f33e1d4 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -104,8 +104,9 @@ void cut_to_eof(void)
/* Move text from the current buffer into the cutbuffer. If
* copy_text is TRUE, copy the text back into the buffer afterward.
* If cut_till_eof is TRUE, move all text from the current cursor
- * position to the end of the file into the cutbuffer. */
-void do_cut_text(bool copy_text, bool marked, bool cut_till_eof)
+ * position to the end of the file into the cutbuffer. If append
+ * is TRUE (when zapping), always append the cut to the cutbuffer. */
+void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append)
{
#ifndef NANO_TINY
filestruct *cb_save = NULL;
@@ -120,7 +121,7 @@ void do_cut_text(bool copy_text, bool marked, bool cut_till_eof)
size_t was_totsize = openfile->totsize;
/* If cuts were not continuous, or when cutting a region, clear the slate. */
- if (!keep_cutbuffer || marked || cut_till_eof) {
+ if (!append && (!keep_cutbuffer || marked || cut_till_eof)) {
free_filestruct(cutbuffer);
cutbuffer = NULL;
/* After a line cut, future line cuts should add to the cutbuffer. */
@@ -193,10 +194,10 @@ void do_cut_text_void(void)
openfile->current_undo->mark_begin_lineno != openfile->current->lineno ||
!keep_cutbuffer)
add_undo(CUT);
- do_cut_text(FALSE, openfile->mark, FALSE);
+ do_cut_text(FALSE, openfile->mark, FALSE, FALSE);
update_undo(CUT);
#else
- do_cut_text(FALSE, FALSE, FALSE);
+ do_cut_text(FALSE, FALSE, FALSE, FALSE);
#endif
}
@@ -218,7 +219,7 @@ void do_copy_text(void)
if (mark_is_set || openfile->current != next_contiguous_line)
cutbuffer_reset();
- do_cut_text(TRUE, mark_is_set, FALSE);
+ do_cut_text(TRUE, mark_is_set, FALSE, FALSE);
/* If the mark was set, blow away the cutbuffer on the next copy. */
next_contiguous_line = (mark_is_set ? NULL : openfile->current);
@@ -236,9 +237,35 @@ void do_copy_text(void)
void do_cut_till_eof(void)
{
add_undo(CUT_TO_EOF);
- do_cut_text(FALSE, FALSE, TRUE);
+ do_cut_text(FALSE, FALSE, TRUE, FALSE);
update_undo(CUT_TO_EOF);
}
+
+/* Erase text (current line or marked region), sending it into oblivion. */
+void zap_text(void)
+{
+ /* Remember the current cutbuffer so it can be restored after the zap. */
+ filestruct *was_cutbuffer = cutbuffer;
+ filestruct *was_cutbottom = cutbottom;
+
+ /* Add a new undo item only when the current item is not a ZAP or when
+ * the current zap is not contiguous with the previous zapping. */
+ if (openfile->last_action != ZAP || openfile->current_undo == NULL ||
+ openfile->current_undo->mark_begin_lineno != openfile->current->lineno ||
+ openfile->current_undo->xflags & (MARK_WAS_SET|WAS_MARKED_FORWARD))
+ add_undo(ZAP);
+
+ /* Use the cutbuffer from the ZAP undo item, so the cut can be undone. */
+ cutbuffer = openfile->current_undo->cutbuffer;
+ cutbottom = openfile->current_undo->cutbottom;
+
+ do_cut_text(FALSE, openfile->mark, FALSE, TRUE);
+
+ update_undo(ZAP);
+
+ cutbuffer = was_cutbuffer;
+ cutbottom = was_cutbottom;
+}
#endif /* !NANO_TINY */
/* Copy text from the cutbuffer into the current buffer. */
diff --git a/src/files.c b/src/files.c
index 5878ff00..4b757c65 100644
--- a/src/files.c
+++ b/src/files.c
@@ -533,7 +533,7 @@ void replace_buffer(const char *filename)
#ifndef NANO_TINY
add_undo(CUT_TO_EOF);
#endif
- do_cut_text(FALSE, FALSE, TRUE);
+ do_cut_text(FALSE, FALSE, TRUE, FALSE);
#ifndef NANO_TINY
update_undo(CUT_TO_EOF);
#endif
@@ -574,7 +574,7 @@ void replace_marked_buffer(const char *filename)
/* Throw away the text under the mark. */
cutbuffer = NULL;
add_undo(CUT);
- do_cut_text(FALSE, TRUE, FALSE);
+ do_cut_text(FALSE, TRUE, FALSE, FALSE);
update_undo(CUT);
free_filestruct(cutbuffer);
cutbuffer = was_cutbuffer;
diff --git a/src/global.c b/src/global.c
index e1d7930f..89df838b 100644
--- a/src/global.c
+++ b/src/global.c
@@ -576,6 +576,7 @@ void shortcut_init(void)
const char *mark_gist = N_("Mark text starting from the cursor position");
const char *copy_gist =
N_("Copy current line (or marked region) and store it in cutbuffer");
+ const char *zap_gist = N_("Throw away the current line (or marked region)");
const char *indent_gist = N_("Indent the current line (or marked lines)");
const char *unindent_gist = N_("Unindent the current line (or marked lines)");
const char *undo_gist = N_("Undo the last operation");
@@ -997,6 +998,11 @@ void shortcut_init(void)
N_("Save"), WITHORSANS(savefile_gist), BLANKAFTER, NOVIEW);
#endif
+#ifndef NANO_TINY
+ add_to_funcs(zap_text, MMAIN,
+ N_("Zap Text"), WITHORSANS(zap_gist), BLANKAFTER, NOVIEW);
+#endif
+
#ifndef ENABLE_JUSTIFY
add_to_funcs(flip_goto, MWHEREIS,
N_("Go To Line"), WITHORSANS(gotoline_gist), BLANKAFTER, VIEW);
@@ -1471,6 +1477,8 @@ sc *strtosc(const char *input)
else if (!strcasecmp(input, "copy") ||
!strcasecmp(input, "copytext")) /* Deprecated. Remove end of 2018. */
s->func = do_copy_text;
+ else if (!strcasecmp(input, "zap"))
+ s->func = zap_text;
else if (!strcasecmp(input, "mark"))
s->func = do_mark;
#endif
diff --git a/src/nano.h b/src/nano.h
index 3007881d..50937695 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -178,7 +178,7 @@ typedef enum {
#ifdef ENABLE_COMMENT
COMMENT, UNCOMMENT, PREFLIGHT,
#endif
- CUT, CUT_TO_EOF, PASTE, INSERT, COUPLE_BEGIN, COUPLE_END, OTHER
+ ZAP, CUT, CUT_TO_EOF, PASTE, INSERT, COUPLE_BEGIN, COUPLE_END, OTHER
} undo_type;
/* Structure types. */
diff --git a/src/proto.h b/src/proto.h
index a157ece0..a2834606 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -249,11 +249,12 @@ void cutbuffer_reset(void);
#ifndef NANO_TINY
void cut_marked(bool *right_side_up);
#endif
-void do_cut_text(bool copy_text, bool marked, bool cut_till_eof);
+void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append);
void do_cut_text_void(void);
#ifndef NANO_TINY
void do_copy_text(void);
void do_cut_till_eof(void);
+void zap_text(void);
#endif
void do_uncut_text(void);
diff --git a/src/text.c b/src/text.c
index 8302c7dd..c9fb4868 100644
--- a/src/text.c
+++ b/src/text.c
@@ -687,7 +687,7 @@ void redo_cut(undo *u)
openfile->mark = fsfromline(u->mark_begin_lineno);
openfile->mark_x = (u->xflags == WAS_WHOLE_LINE) ? 0 : u->mark_begin_x;
- do_cut_text(FALSE, TRUE, FALSE);
+ do_cut_text(FALSE, TRUE, FALSE, u->type == ZAP);
free_filestruct(cutbuffer);
cutbuffer = oldcutbuffer;
@@ -792,6 +792,10 @@ void do_undo(void)
undidmsg = _("text add");
break;
#endif
+ case ZAP:
+ undidmsg = _("erasure");
+ undo_cut(u);
+ break;
case CUT_TO_EOF:
case CUT:
undidmsg = _("text cut");
@@ -968,6 +972,10 @@ void do_redo(void)
redidmsg = _("text add");
break;
#endif
+ case ZAP:
+ redidmsg = _("erasure");
+ redo_cut(u);
+ break;
case CUT_TO_EOF:
case CUT:
redidmsg = _("text cut");
@@ -1201,7 +1209,7 @@ bool execute_command(const char *command)
if (ISSET(MULTIBUFFER)) {
switch_to_prev_buffer();
if (openfile->mark)
- do_cut_text(TRUE, TRUE, FALSE);
+ do_cut_text(TRUE, TRUE, FALSE, FALSE);
} else
#endif
{
@@ -1212,7 +1220,7 @@ bool execute_command(const char *command)
openfile->current_x = 0;
}
add_undo(CUT);
- do_cut_text(FALSE, openfile->mark, openfile->mark == NULL);
+ do_cut_text(FALSE, openfile->mark, openfile->mark == NULL, FALSE);
update_undo(CUT);
}
@@ -1403,6 +1411,7 @@ void add_undo(undo_type action)
#endif
case CUT_TO_EOF:
break;
+ case ZAP:
case CUT:
if (openfile->mark) {
u->mark_begin_lineno = openfile->mark->lineno;
@@ -1529,12 +1538,17 @@ void update_undo(undo_type action)
case SPLIT_END:
break;
#endif
+ case ZAP:
case CUT_TO_EOF:
case CUT:
if (!cutbuffer)
break;
- free_filestruct(u->cutbuffer);
- u->cutbuffer = copy_filestruct(cutbuffer);
+ if (u->type == ZAP)
+ u->cutbuffer = cutbuffer;
+ else {
+ free_filestruct(u->cutbuffer);
+ u->cutbuffer = copy_filestruct(cutbuffer);
+ }
if (u->xflags == MARK_WAS_SET) {
/* If the "marking" operation was from right-->left or
* bottom-->top, then swap the mark points. */
--
2.19.1
2.19.1