replacing: make spotlight() account for varying chunk width

spotlight() now displays softwrapped lines chunk by chunk instead of all
at once.  Since softwrapped lines are no longer of constant width, the
latter approach would fail if softwrapping breaks the spotlighted text.

Instead of taking a string, spotlight() now takes the starting and ending
columns of that string.  Also, its handling of softwrapped lines is now
split off into a separate function, spotlight_softwrapped().
This commit is contained in:
David Lawrence Ramsey 2017-03-06 01:34:45 -06:00 committed by Benno Schulenberg
parent a4c2eaa2e6
commit aa04ad4f83
4 changed files with 105 additions and 33 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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,9 +3440,71 @@ 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
#define XLCREDIT_LEN 9