tweaks: move the character/word-deletion functions to a better location

Having all the cutting and deleting functions together in one file
kind of makes sense.
master
Benno Schulenberg 2019-01-01 17:29:08 +01:00
parent f9bb5382aa
commit 16c20ad873
3 changed files with 187 additions and 189 deletions

183
src/cut.c
View File

@ -24,6 +24,189 @@
#include <string.h>
/* Delete the character under the cursor. */
void do_deletion(undo_type action)
{
#ifndef NANO_TINY
size_t old_amount = 0;
#endif
openfile->placewewant = xplustabs();
/* When in the middle of a line, delete the current character. */
if (openfile->current->data[openfile->current_x] != '\0') {
int char_len = parse_mbchar(openfile->current->data +
openfile->current_x, NULL, NULL);
size_t line_len = strlen(openfile->current->data +
openfile->current_x);
#ifndef NANO_TINY
/* If the type of action changed or the cursor moved to a different
* line, create a new undo item, otherwise update the existing item. */
if (action != openfile->last_action ||
openfile->current->lineno != openfile->current_undo->lineno)
add_undo(action);
else
update_undo(action);
if (ISSET(SOFTWRAP))
old_amount = number_of_chunks_in(openfile->current);
#endif
/* Move the remainder of the line "in", over the current character. */
charmove(&openfile->current->data[openfile->current_x],
&openfile->current->data[openfile->current_x + char_len],
line_len - char_len + 1);
#ifndef NANO_TINY
/* Adjust the mark if it is after the cursor on the current line. */
if (openfile->mark == openfile->current &&
openfile->mark_x > openfile->current_x)
openfile->mark_x -= char_len;
#endif
/* Otherwise, when not at end of buffer, join this line with the next. */
} else if (openfile->current != openfile->filebot) {
filestruct *joining = openfile->current->next;
/* If there is a magic line, and we're before it: don't eat it. */
if (joining == openfile->filebot && openfile->current_x != 0 &&
!ISSET(NO_NEWLINES)) {
#ifndef NANO_TINY
if (action == BACK)
add_undo(BACK);
#endif
return;
}
#ifndef NANO_TINY
add_undo(action);
#endif
/* Add the contents of the next line to those of the current one. */
openfile->current->data = charealloc(openfile->current->data,
strlen(openfile->current->data) + strlen(joining->data) + 1);
strcat(openfile->current->data, joining->data);
#ifndef NANO_TINY
/* Adjust the mark if it was on the line that was "eaten". */
if (openfile->mark == joining) {
openfile->mark = openfile->current;
openfile->mark_x += openfile->current_x;
}
#endif
unlink_node(joining);
renumber(openfile->current);
/* Two lines were joined, so we need to refresh the screen. */
refresh_needed = TRUE;
} else
/* We're at the end-of-file: nothing to do. */
return;
/* Adjust the file size, and remember it for a possible redo. */
openfile->totsize--;
#ifndef NANO_TINY
openfile->current_undo->newsize = openfile->totsize;
/* If the number of screen rows that a softwrapped line occupies
* has changed, we need a full refresh. */
if (ISSET(SOFTWRAP) && refresh_needed == FALSE &&
number_of_chunks_in(openfile->current) != old_amount)
refresh_needed = TRUE;
#endif
set_modified();
}
/* Delete the character under the cursor. */
void do_delete(void)
{
#ifndef NANO_TINY
if (openfile->mark && ISSET(LET_THEM_ZAP))
zap_text();
else
#endif
do_deletion(DEL);
}
/* Backspace over one character. That is, move the cursor left one
* character, and then delete the character under the cursor. */
void do_backspace(void)
{
#ifndef NANO_TINY
if (openfile->mark && ISSET(LET_THEM_ZAP))
zap_text();
else
#endif
if (openfile->current != openfile->fileage || openfile->current_x > 0) {
do_left();
do_deletion(BACK);
}
}
#ifndef NANO_TINY
/* Delete text from the cursor until the first start of a word to
* the right, or to the left when backward is true. */
void do_cutword(bool backward)
{
/* Remember the current cursor position. */
filestruct *is_current = openfile->current;
size_t is_current_x = openfile->current_x;
/* Remember where the cutbuffer is and then make it seem blank. */
filestruct *is_cutbuffer = cutbuffer;
filestruct *is_cutbottom = cutbottom;
cutbuffer = NULL;
cutbottom = NULL;
/* Move the cursor to a word start, to the left or to the right.
* If that word is on another line and the cursor was not already
* on the edge of the original line, then put the cursor on that
* edge instead, so that lines will not be joined unexpectedly. */
if (backward) {
do_prev_word(ISSET(WORD_BOUNDS));
if (openfile->current != is_current) {
if (is_current_x > 0) {
openfile->current = is_current;
openfile->current_x = 0;
} else
openfile->current_x = strlen(openfile->current->data);
}
} else {
do_next_word(FALSE, ISSET(WORD_BOUNDS));
if (openfile->current != is_current &&
is_current->data[is_current_x] != '\0') {
openfile->current = is_current;
openfile->current_x = strlen(is_current->data);
}
}
/* Set the mark at the start of that word. */
openfile->mark = openfile->current;
openfile->mark_x = openfile->current_x;
/* Put the cursor back where it was, so an undo will put it there too. */
openfile->current = is_current;
openfile->current_x = is_current_x;
/* Now kill the marked region and a word is gone. */
do_cut_text_void();
/* Discard the cut word and restore the cutbuffer. */
free_filestruct(cutbuffer);
cutbuffer = is_cutbuffer;
cutbottom = is_cutbottom;
}
/* Delete a word leftward. */
void do_cut_prev_word(void)
{
do_cutword(TRUE);
}
/* Delete a word rightward. */
void do_cut_next_word(void)
{
do_cutword(FALSE);
}
#endif /* !NANO_TINY */
/* If we aren't on the last line of the file, move all the text of the
* current line, plus the newline at the end, into the cutbuffer. If we
* are, move all of the text of the current line into the cutbuffer. In

View File

@ -243,7 +243,11 @@ void precalc_multicolorinfo(void);
#endif
/* Most functions in cut.c. */
void do_delete(void);
void do_backspace(void);
#ifndef NANO_TINY
void do_cut_prev_word(void);
void do_cut_next_word(void);
void cut_marked(bool *right_side_up);
#endif
void do_cut_text(bool copy_text, bool marked, bool cut_till_eof, bool append);
@ -492,12 +496,6 @@ void do_find_bracket(void);
#ifndef NANO_TINY
void do_mark(void);
#endif
void do_delete(void);
void do_backspace(void);
#ifndef NANO_TINY
void do_cut_prev_word(void);
void do_cut_next_word(void);
#endif
void do_tab(void);
#ifndef NANO_TINY
void do_indent(void);

View File

@ -76,189 +76,6 @@ char *invocation_error(const char *name)
}
#endif
/* Delete the character under the cursor. */
void do_deletion(undo_type action)
{
#ifndef NANO_TINY
size_t old_amount = 0;
#endif
openfile->placewewant = xplustabs();
/* When in the middle of a line, delete the current character. */
if (openfile->current->data[openfile->current_x] != '\0') {
int char_len = parse_mbchar(openfile->current->data +
openfile->current_x, NULL, NULL);
size_t line_len = strlen(openfile->current->data +
openfile->current_x);
#ifndef NANO_TINY
/* If the type of action changed or the cursor moved to a different
* line, create a new undo item, otherwise update the existing item. */
if (action != openfile->last_action ||
openfile->current->lineno != openfile->current_undo->lineno)
add_undo(action);
else
update_undo(action);
if (ISSET(SOFTWRAP))
old_amount = number_of_chunks_in(openfile->current);
#endif
/* Move the remainder of the line "in", over the current character. */
charmove(&openfile->current->data[openfile->current_x],
&openfile->current->data[openfile->current_x + char_len],
line_len - char_len + 1);
#ifndef NANO_TINY
/* Adjust the mark if it is after the cursor on the current line. */
if (openfile->mark == openfile->current &&
openfile->mark_x > openfile->current_x)
openfile->mark_x -= char_len;
#endif
/* Otherwise, when not at end of buffer, join this line with the next. */
} else if (openfile->current != openfile->filebot) {
filestruct *joining = openfile->current->next;
/* If there is a magic line, and we're before it: don't eat it. */
if (joining == openfile->filebot && openfile->current_x != 0 &&
!ISSET(NO_NEWLINES)) {
#ifndef NANO_TINY
if (action == BACK)
add_undo(BACK);
#endif
return;
}
#ifndef NANO_TINY
add_undo(action);
#endif
/* Add the contents of the next line to those of the current one. */
openfile->current->data = charealloc(openfile->current->data,
strlen(openfile->current->data) + strlen(joining->data) + 1);
strcat(openfile->current->data, joining->data);
#ifndef NANO_TINY
/* Adjust the mark if it was on the line that was "eaten". */
if (openfile->mark == joining) {
openfile->mark = openfile->current;
openfile->mark_x += openfile->current_x;
}
#endif
unlink_node(joining);
renumber(openfile->current);
/* Two lines were joined, so we need to refresh the screen. */
refresh_needed = TRUE;
} else
/* We're at the end-of-file: nothing to do. */
return;
/* Adjust the file size, and remember it for a possible redo. */
openfile->totsize--;
#ifndef NANO_TINY
openfile->current_undo->newsize = openfile->totsize;
/* If the number of screen rows that a softwrapped line occupies
* has changed, we need a full refresh. */
if (ISSET(SOFTWRAP) && refresh_needed == FALSE &&
number_of_chunks_in(openfile->current) != old_amount)
refresh_needed = TRUE;
#endif
set_modified();
}
/* Delete the character under the cursor. */
void do_delete(void)
{
#ifndef NANO_TINY
if (openfile->mark && ISSET(LET_THEM_ZAP))
zap_text();
else
#endif
do_deletion(DEL);
}
/* Backspace over one character. That is, move the cursor left one
* character, and then delete the character under the cursor. */
void do_backspace(void)
{
#ifndef NANO_TINY
if (openfile->mark && ISSET(LET_THEM_ZAP))
zap_text();
else
#endif
if (openfile->current != openfile->fileage || openfile->current_x > 0) {
do_left();
do_deletion(BACK);
}
}
#ifndef NANO_TINY
/* Delete text from the cursor until the first start of a word to
* the right, or to the left when backward is true. */
void do_cutword(bool backward)
{
/* Remember the current cursor position. */
filestruct *is_current = openfile->current;
size_t is_current_x = openfile->current_x;
/* Remember where the cutbuffer is and then make it seem blank. */
filestruct *is_cutbuffer = cutbuffer;
filestruct *is_cutbottom = cutbottom;
cutbuffer = NULL;
cutbottom = NULL;
/* Move the cursor to a word start, to the left or to the right.
* If that word is on another line and the cursor was not already
* on the edge of the original line, then put the cursor on that
* edge instead, so that lines will not be joined unexpectedly. */
if (backward) {
do_prev_word(ISSET(WORD_BOUNDS));
if (openfile->current != is_current) {
if (is_current_x > 0) {
openfile->current = is_current;
openfile->current_x = 0;
} else
openfile->current_x = strlen(openfile->current->data);
}
} else {
do_next_word(FALSE, ISSET(WORD_BOUNDS));
if (openfile->current != is_current &&
is_current->data[is_current_x] != '\0') {
openfile->current = is_current;
openfile->current_x = strlen(is_current->data);
}
}
/* Set the mark at the start of that word. */
openfile->mark = openfile->current;
openfile->mark_x = openfile->current_x;
/* Put the cursor back where it was, so an undo will put it there too. */
openfile->current = is_current;
openfile->current_x = is_current_x;
/* Now kill the marked region and a word is gone. */
do_cut_text_void();
/* Discard the cut word and restore the cutbuffer. */
free_filestruct(cutbuffer);
cutbuffer = is_cutbuffer;
cutbottom = is_cutbottom;
}
/* Delete a word leftward. */
void do_cut_prev_word(void)
{
do_cutword(TRUE);
}
/* Delete a word rightward. */
void do_cut_next_word(void)
{
do_cutword(FALSE);
}
#endif /* !NANO_TINY */
/* Insert a tab. If the TABS_TO_SPACES flag is set, insert the number
* of spaces that a tab would normally take up. */
void do_tab(void)