nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit 5662a388020e0e7c5068cddb19f172eed360c3fe
parent 02eaa4ce6dc7f887969cd68be5cc42e3c04c9f63
Author: Brand Huntsman <alpha@qzx.com>
Date:   Tue, 23 Oct 2018 20:25:22 -0600

new feature: a bindable 'zap', to erase text without changing cutbuffer

This function allows the user to "make space": annihilating lines or
regions while keeping intact for pasting the stuff in the cutbuffer
that was cut or copied earlier.

Signed-off-by: Brand Huntsman <alpha@qzx.com>

Diffstat:
Mdoc/nano.texi | 3+++
Mdoc/nanorc.5 | 3+++
Msrc/cut.c | 41++++++++++++++++++++++++++++++++++-------
Msrc/files.c | 4++--
Msrc/global.c | 6++++++
Msrc/nano.h | 2+-
Msrc/proto.h | 3++-
Msrc/text.c | 24+++++++++++++++++++-----
8 files changed, 70 insertions(+), 16 deletions(-)

diff --git 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 @@ -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 @@ -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 @@ -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 @@ -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"); @@ -988,6 +989,9 @@ void shortcut_init(void) add_to_funcs(run_macro, MMAIN, N_("Run Macro"), WITHORSANS(runmacro_gist), BLANKAFTER, VIEW); + add_to_funcs(zap_text, MMAIN, + N_("Zap Text"), WITHORSANS(zap_gist), BLANKAFTER, NOVIEW); + #ifdef ENABLE_COLOR if (!ISSET(RESTRICTED)) add_to_funcs(do_linter, MMAIN, @@ -1471,6 +1475,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 @@ -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 @@ -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 @@ -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. */