From 8e58d9fd401bb2a17474f6bc1ce90a63c2950297 Mon Sep 17 00:00:00 2001 From: Mark-Weston Date: Sun, 5 Aug 2018 03:43:03 +0300 Subject: [PATCH] Improve cutting words When cutting words, the cursor will now stop at line beginnings and ends. --- src/move.c | 27 +++++++++++++++++++-------- src/proto.h | 5 +++-- src/text.c | 6 +++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/move.c b/src/move.c index bf6a0c11..66202ab8 100644 --- a/src/move.c +++ b/src/move.c @@ -271,12 +271,15 @@ void do_next_block(void) edit_redraw(was_current, CENTERING); } -/* Move to the previous word. If allow_punct is TRUE, treat punctuation - * as part of a word. When requested, update the screen afterwards. */ -void do_prev_word(bool allow_punct, bool update_screen) +/* Move to the previous word. If at_line_beginnings is TRUE, stop at line + * beginnings. If allow_punct is TRUE, treat punctuation as part of a word. + * When requested, update the screen afterwards. */ +void do_prev_word(bool at_line_beginnings, bool allow_punct, + bool update_screen) { filestruct *was_current = openfile->current; bool seen_a_word = FALSE, step_forward = FALSE; + bool started_on_line_beginning = openfile->current_x == 0; /* Move backward until we pass over the start of a word. */ while (TRUE) { @@ -284,6 +287,8 @@ void do_prev_word(bool allow_punct, bool update_screen) if (openfile->current_x == 0) { if (openfile->current->prev == NULL) break; + if (at_line_beginnings && !started_on_line_beginning) + break; openfile->current = openfile->current->prev; openfile->current_x = strlen(openfile->current->data); } @@ -315,12 +320,16 @@ void do_prev_word(bool allow_punct, bool update_screen) } /* Move to the next word. If after_ends is TRUE, stop at the ends of words - * instead of their beginnings. If allow_punct is TRUE, treat punctuation - * as part of a word. When requested, update the screen afterwards. + * instead of their beginnings. If at_line_ends is TRUE, stop at line ends. + * If allow_punct is TRUE, treat punctuation as part of a word. + * When requested, update the screen afterwards. * Return TRUE if we started on a word, and FALSE otherwise. */ -bool do_next_word(bool after_ends, bool allow_punct, bool update_screen) +bool do_next_word(bool after_ends, bool at_line_ends, bool allow_punct, + bool update_screen) { filestruct *was_current = openfile->current; + bool started_on_line_end = + openfile->current->data[openfile->current_x] == '\0'; bool started_on_word = is_word_mbchar(openfile->current->data + openfile->current_x, allow_punct); bool seen_space = !started_on_word; @@ -335,6 +344,8 @@ bool do_next_word(bool after_ends, bool allow_punct, bool update_screen) /* When at end of file, stop. */ if (openfile->current->next == NULL) break; + if (at_line_ends && !started_on_line_end) + break; openfile->current = openfile->current->next; openfile->current_x = 0; seen_space = TRUE; @@ -377,7 +388,7 @@ bool do_next_word(bool after_ends, bool allow_punct, bool update_screen) * word if the WORD_BOUNDS flag is set, and update the screen afterwards. */ void do_prev_word_void(void) { - do_prev_word(ISSET(WORD_BOUNDS), TRUE); + do_prev_word(FALSE, ISSET(WORD_BOUNDS), TRUE); } /* Move to the next word in the file. If the AFTER_ENDS flag is set, stop @@ -385,7 +396,7 @@ void do_prev_word_void(void) * punctuation as part of a word. Update the screen afterwards. */ void do_next_word_void(void) { - do_next_word(ISSET(AFTER_ENDS), ISSET(WORD_BOUNDS), TRUE); + do_next_word(ISSET(AFTER_ENDS), FALSE, ISSET(WORD_BOUNDS), TRUE); } /* Move to the beginning of the current line (or softwrapped chunk). diff --git a/src/proto.h b/src/proto.h index e9cc8d9b..d8c06395 100644 --- a/src/proto.h +++ b/src/proto.h @@ -376,8 +376,9 @@ void do_para_end_void(void); #endif void do_prev_block(void); void do_next_block(void); -void do_prev_word(bool allow_punct, bool update_screen); -bool do_next_word(bool after_ends, bool allow_punct, bool update_screen); +void do_prev_word(bool at_line_beginnings, bool allow_punct, bool update_screen); +bool do_next_word(bool after_ends, bool at_line_ends, bool allow_punct, + bool update_screen); void do_prev_word_void(void); void do_next_word_void(void); void do_home(void); diff --git a/src/text.c b/src/text.c index 99eaa512..1ba82526 100644 --- a/src/text.c +++ b/src/text.c @@ -207,9 +207,9 @@ void do_cutword(bool backward) /* Move the cursor to a word start, to the left or to the right. */ if (backward) - do_prev_word(ISSET(WORD_BOUNDS), FALSE); + do_prev_word(TRUE, ISSET(WORD_BOUNDS), FALSE); else - do_next_word(FALSE, ISSET(WORD_BOUNDS), FALSE); + do_next_word(FALSE, TRUE, ISSET(WORD_BOUNDS), FALSE); /* Set the mark at the start of that word. */ openfile->mark = openfile->current; @@ -3457,7 +3457,7 @@ void do_wordlinechar_count(void) * count whenever we're on a word just before moving. */ while (openfile->current != openfile->filebot || openfile->current->data[openfile->current_x] != '\0') { - if (do_next_word(FALSE, TRUE, FALSE)) + if (do_next_word(FALSE, FALSE, TRUE, FALSE)) words++; } -- 2.18.0