diff --git a/src/proto.h b/src/proto.h index aabca6ab8efda5c6b03fc2386813d7cccb388e47..605f2cde12302d397a3ad69a3df6598f90a805df 100644 --- a/src/proto.h +++ b/src/proto.h @@ -681,7 +681,10 @@ void total_refresh(void); void display_main_list(void); void do_cursorpos(bool force); void do_cursorpos_void(void); -void spotlight(bool active, const char *word); +void spotlight(bool active, size_t from_col, size_t to_col); +#ifndef NANO_TINY +void spotlight_softwrapped(bool active, size_t from_col, size_t to_col); +#endif void xon_complaint(void); void xoff_complaint(void); void do_suspend_void(void); diff --git a/src/search.c b/src/search.c index 6d178200aa491b8509469b15f905d8d6b536e926..2c36a5b5bf0c378a82c5daefa6424a37d52ba5c1 100644 --- a/src/search.c +++ b/src/search.c @@ -614,10 +614,9 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only, numreplaced = 0; if (!replaceall) { - size_t xpt = xplustabs(); - char *exp_word = display_string(openfile->current->data, - xpt, strnlenpt(openfile->current->data, - openfile->current_x + match_len) - xpt, FALSE); + size_t from_col = xplustabs(); + size_t to_col = strnlenpt(openfile->current->data, + openfile->current_x + match_len); /* Refresh the edit window, scrolling it if necessary. */ edit_refresh(); @@ -625,14 +624,12 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only, /* Don't show cursor, to not distract from highlighted match. */ curs_set(0); - spotlight(TRUE, exp_word); + spotlight(TRUE, from_col, to_col); /* TRANSLATORS: This is a prompt. */ i = do_yesno_prompt(TRUE, _("Replace this instance?")); - spotlight(FALSE, exp_word); - - free(exp_word); + spotlight(FALSE, from_col, to_col); if (i == -1) /* The replacing was cancelled. */ break; diff --git a/src/text.c b/src/text.c index 3bb76c082ec3ebf6c017d1cfe9a7bc1e71c5f65d..4a8d38cf1962d1ad3fb391b5b117cd50c03fb062 100644 --- a/src/text.c +++ b/src/text.c @@ -2540,7 +2540,7 @@ void do_full_justify(void) * return FALSE if the user cancels. */ bool do_int_spell_fix(const char *word) { - char *save_search, *exp_word; + char *save_search; size_t firstcolumn_save = openfile->firstcolumn; size_t current_x_save = openfile->current_x; filestruct *edittop_save = openfile->edittop; @@ -2605,11 +2605,12 @@ bool do_int_spell_fix(const char *word) proceed = TRUE; napms(2800); } else if (result == 1) { - exp_word = display_string(openfile->current->data, xplustabs(), - strlenpt(word), FALSE); + size_t from_col = xplustabs(); + size_t to_col = from_col + strlenpt(word); + edit_refresh(); - spotlight(TRUE, exp_word); + spotlight(TRUE, from_col, to_col); /* Let the user supply a correctly spelled alternative. */ proceed = (do_prompt(FALSE, FALSE, MSPELL, word, @@ -2618,9 +2619,7 @@ bool do_int_spell_fix(const char *word) #endif edit_refresh, _("Edit a replacement")) != -1); - spotlight(FALSE, exp_word); - - free(exp_word); + spotlight(FALSE, from_col, to_col); /* If a replacement was given, go through all occurrences. */ if (proceed && strcmp(word, answer) != 0) { diff --git a/src/winio.c b/src/winio.c index c8e8cc77e52b1b30d852f7f48ff7be3230b4c2c7..8c1edcfd93c894eb216917651667491c234498e0 100644 --- a/src/winio.c +++ b/src/winio.c @@ -3396,32 +3396,43 @@ void enable_waiting(void) nodelay(edit, FALSE); } -/* Highlight the current word being replaced or spell checked. We - * expect word to have tabs and control characters expanded. */ -void spotlight(bool active, const char *word) +/* Highlight the text between from_col and to_col when active is TRUE. + * Remove the highlight when active is FALSE. */ +void spotlight(bool active, size_t from_col, size_t to_col) { - size_t word_span = strlenpt(word); - size_t room = word_span; + char *word; + size_t word_span, room; - /* Compute the number of columns that are available for the word. */ - if (!ISSET(SOFTWRAP)) { - room = editwincols + get_page_start(xplustabs()) - xplustabs(); - - /* If the word is partially offscreen, reserve space for the "$". */ - if (word_span > room) - room--; +#ifndef NANO_TINY + if (ISSET(SOFTWRAP)) { + spotlight_softwrapped(active, from_col, to_col); + return; } +#endif place_the_cursor(FALSE); + /* This is so we can show zero-length matches. */ + if (to_col == from_col) { + word = mallocstrcpy(NULL, " "); + to_col++; + } else + word = display_string(openfile->current->data, from_col, + to_col - from_col, FALSE); + + word_span = strlenpt(word); + + /* Compute the number of columns that are available for the word. */ + room = editwincols + get_page_start(from_col) - from_col; + + /* If the word is partially offscreen, reserve space for the "$". */ + if (word_span > room) + room--; + if (active) wattron(edit, hilite_attribute); - /* This is so we can show zero-length matches. */ - if (word_span == 0) - waddch(edit, ' '); - else - waddnstr(edit, word, actual_x(word, room)); + waddnstr(edit, word, actual_x(word, room)); if (word_span > room) waddch(edit, '$'); @@ -3429,8 +3440,70 @@ void spotlight(bool active, const char *word) if (active) wattroff(edit, hilite_attribute); + free(word); + + wnoutrefresh(edit); +} + +#ifndef NANO_TINY +/* Highlight the text between from_col and to_col when active is TRUE; remove + * the highlight when active is FALSE. This will not highlight softwrapped + * line breaks, since they're not actually part of the spotlighted text. */ +void spotlight_softwrapped(bool active, size_t from_col, size_t to_col) +{ + ssize_t row; + size_t leftedge = get_chunk_leftedge(openfile->current, from_col); + size_t break_col; + bool end_of_line; + char *word; + + place_the_cursor(FALSE); + + row = openfile->current_y; + + while (row < editwinrows) { + break_col = get_softwrap_breakpoint(openfile->current->data, + leftedge, &end_of_line); + + /* Stop after the end of the word, by pretending the end of the word is + * the end of the line. */ + if (break_col >= to_col) { + end_of_line = TRUE; + break_col = to_col; + } + + /* This is so we can show zero-length matches. */ + if (break_col == from_col) { + word = mallocstrcpy(NULL, " "); + break_col++; + } else + word = display_string(openfile->current->data, from_col, + break_col - from_col, FALSE); + + if (active) + wattron(edit, hilite_attribute); + + waddnstr(edit, word, actual_x(word, break_col)); + + if (active) + wattroff(edit, hilite_attribute); + + free(word); + + if (end_of_line) + break; + + row++; + + wmove(edit, row, 0); + + leftedge = break_col; + from_col = break_col; + } + wnoutrefresh(edit); } +#endif #ifndef DISABLE_EXTRA #define CREDIT_LEN 54