speller: fix replacing marked text in the alternate spell checker
With read_file() revamped, it now uses partition_filestruct() indirectly via ingraft_buffer(), so we can't use partition_filestruct() to replace marked text in the alternate spell checker anymore without segfaulting. Add the new function replace_marked_buffer() to accomplish this instead. Based on replace_buffer(), it uses extract_buffer() to throw away the marked un-spell-checked text, and then uses read_file() to insert the spell-checked text at the position where the mark was. Accordingly, remove unneeded partitioning and related stuff from do_alt_speller(). Besides pasting the file into the buffer at current[current_x], ingraft_buffer() also deals with renumbering, updating totsize, and handling a magicline, so do_alt_speller() doesn't need to do those anymore.master
parent
0d9313763d
commit
234bd9c9be
33
src/files.c
33
src/files.c
|
@ -545,6 +545,39 @@ void replace_buffer(const char *filename)
|
||||||
/* Put current at a place that is certain to exist. */
|
/* Put current at a place that is certain to exist. */
|
||||||
openfile->current = openfile->fileage;
|
openfile->current = openfile->fileage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NANO_TINY
|
||||||
|
/* Open the specified file, and if that succeeds, blow away the text of
|
||||||
|
* the current buffer at the given coordinates and read the file
|
||||||
|
* contents into its place. */
|
||||||
|
void replace_marked_buffer(const char *filename, filestruct *top, size_t top_x,
|
||||||
|
filestruct *bot, size_t bot_x)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
int descriptor;
|
||||||
|
bool old_no_newlines = ISSET(NO_NEWLINES);
|
||||||
|
filestruct *trash_top = NULL;
|
||||||
|
filestruct *trash_bot = NULL;
|
||||||
|
|
||||||
|
descriptor = open_file(filename, FALSE, TRUE, &f);
|
||||||
|
|
||||||
|
if (descriptor < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Don't add a magicline when replacing text in the buffer. */
|
||||||
|
SET(NO_NEWLINES);
|
||||||
|
|
||||||
|
/* Throw away the text under the mark, and insert the processed file
|
||||||
|
* where the marked text was. */
|
||||||
|
extract_buffer(&trash_top, &trash_bot, top, top_x, bot, bot_x);
|
||||||
|
free_filestruct(trash_top);
|
||||||
|
read_file(f, descriptor, filename, FALSE, TRUE);
|
||||||
|
|
||||||
|
/* Restore the magicline behavior now that we're done fiddling. */
|
||||||
|
if (!old_no_newlines)
|
||||||
|
UNSET(NO_NEWLINES);
|
||||||
|
}
|
||||||
|
#endif /* !ENABLE_TINY */
|
||||||
#endif /* !DISABLE_SPELLER */
|
#endif /* !DISABLE_SPELLER */
|
||||||
|
|
||||||
/* Update the screen to account for the current buffer. */
|
/* Update the screen to account for the current buffer. */
|
||||||
|
|
|
@ -294,6 +294,10 @@ void initialize_buffer_text(void);
|
||||||
bool open_buffer(const char *filename, bool undoable);
|
bool open_buffer(const char *filename, bool undoable);
|
||||||
#ifndef DISABLE_SPELLER
|
#ifndef DISABLE_SPELLER
|
||||||
void replace_buffer(const char *filename);
|
void replace_buffer(const char *filename);
|
||||||
|
#ifndef NANO_TINY
|
||||||
|
void replace_marked_buffer(const char *filename, filestruct *top, size_t top_x,
|
||||||
|
filestruct *bot, size_t bot_x);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void display_buffer(void);
|
void display_buffer(void);
|
||||||
#ifndef DISABLE_MULTIBUFFER
|
#ifndef DISABLE_MULTIBUFFER
|
||||||
|
|
72
src/text.c
72
src/text.c
|
@ -2880,19 +2880,11 @@ const char *do_alt_speller(char *tempfile_name)
|
||||||
static int arglen = 3;
|
static int arglen = 3;
|
||||||
static char **spellargs = NULL;
|
static char **spellargs = NULL;
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
bool old_mark_set = openfile->mark_set;
|
|
||||||
bool added_magicline = FALSE;
|
|
||||||
/* Whether we added a magicline after filebot. */
|
|
||||||
filestruct *top, *bot;
|
filestruct *top, *bot;
|
||||||
size_t top_x, bot_x, was_x, new_x;
|
size_t top_x, bot_x;
|
||||||
bool right_side_up = FALSE;
|
bool right_side_up = FALSE;
|
||||||
|
bool old_mark_set = openfile->mark_set;
|
||||||
ssize_t mb_lineno_save = 0;
|
ssize_t mb_lineno_save = 0;
|
||||||
/* We're going to close the current file, and open the output of
|
|
||||||
* the alternate spell command. The line that mark_begin points
|
|
||||||
* to will be freed, so we save the line number and restore it
|
|
||||||
* afterwards. */
|
|
||||||
size_t size_of_surrounding = 0;
|
|
||||||
/* The size of the text outside of a marked region. */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get the timestamp and the size of the temporary file. */
|
/* Get the timestamp and the size of the temporary file. */
|
||||||
|
@ -2904,9 +2896,8 @@ const char *do_alt_speller(char *tempfile_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
|
/* Save the mark's position and turn it off. */
|
||||||
if (old_mark_set) {
|
if (old_mark_set) {
|
||||||
/* If the mark is on, save the number of the line it starts on,
|
|
||||||
* and then turn the mark off. */
|
|
||||||
mb_lineno_save = openfile->mark_begin->lineno;
|
mb_lineno_save = openfile->mark_begin->lineno;
|
||||||
openfile->mark_set = FALSE;
|
openfile->mark_set = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2965,65 +2956,28 @@ const char *do_alt_speller(char *tempfile_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
|
/* Replace the text (or just the marked text) of the current buffer
|
||||||
|
* with the spell-checked text. */
|
||||||
if (old_mark_set) {
|
if (old_mark_set) {
|
||||||
/* Trim the filestruct so that it contains only the marked text. */
|
|
||||||
mark_order((const filestruct **)&top, &top_x,
|
mark_order((const filestruct **)&top, &top_x,
|
||||||
(const filestruct **)&bot, &bot_x, &right_side_up);
|
(const filestruct **)&bot, &bot_x, &right_side_up);
|
||||||
filepart = partition_filestruct(top, top_x, bot, bot_x);
|
|
||||||
|
|
||||||
/* Foresay whether a magicline will be added when the
|
replace_marked_buffer(tempfile_name, top, top_x, bot, bot_x);
|
||||||
* spell-checked text is read back in. */
|
|
||||||
if (!ISSET(NO_NEWLINES))
|
|
||||||
added_magicline = (openfile->filebot->data[0] != '\0');
|
|
||||||
|
|
||||||
/* Compute the size of the text outside of the marked region. */
|
|
||||||
size_of_surrounding = openfile->totsize - get_totsize(top, bot);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Replace the text of the current buffer with the spell-checked text. */
|
|
||||||
replace_buffer(tempfile_name);
|
|
||||||
|
|
||||||
#ifndef NANO_TINY
|
|
||||||
if (old_mark_set) {
|
|
||||||
filestruct *top_save = openfile->fileage;
|
|
||||||
|
|
||||||
/* If a magicline was added, remove it again. */
|
|
||||||
if (added_magicline)
|
|
||||||
remove_magicline();
|
|
||||||
|
|
||||||
/* Adjust the end point of the marked region for any change in
|
/* Adjust the end point of the marked region for any change in
|
||||||
* length of the region's last line. */
|
* length of the region's last line. */
|
||||||
if (right_side_up)
|
if (right_side_up)
|
||||||
was_x = current_x_save;
|
current_x_save = openfile->current_x;
|
||||||
else
|
else
|
||||||
was_x = openfile->mark_begin_x;
|
openfile->mark_begin_x = openfile->current_x;
|
||||||
if (top == bot)
|
|
||||||
new_x = was_x - bot_x + top_x + strlen(openfile->filebot->data);
|
|
||||||
else
|
|
||||||
new_x = strlen(openfile->filebot->data);
|
|
||||||
if (right_side_up)
|
|
||||||
current_x_save = new_x;
|
|
||||||
else
|
|
||||||
openfile->mark_begin_x = new_x;
|
|
||||||
|
|
||||||
/* Unpartition the filestruct so that it contains all the text
|
/* Restore the mark's position and turn it on. */
|
||||||
* again. Note that we've replaced the marked text originally
|
|
||||||
* in the partition with the spell-checked marked text in the
|
|
||||||
* temp file. */
|
|
||||||
unpartition_filestruct(&filepart);
|
|
||||||
|
|
||||||
/* Renumber, starting with the beginning line of the old partition. */
|
|
||||||
renumber(top_save);
|
|
||||||
|
|
||||||
/* Add back the size of the text surrounding the marked region. */
|
|
||||||
openfile->totsize += size_of_surrounding;
|
|
||||||
|
|
||||||
/* Restore the position of the mark, and turn it back on. */
|
|
||||||
openfile->mark_begin = fsfromline(mb_lineno_save);
|
openfile->mark_begin = fsfromline(mb_lineno_save);
|
||||||
openfile->mark_set = TRUE;
|
openfile->mark_set = TRUE;
|
||||||
}
|
} else
|
||||||
#endif /* !NANO_TINY */
|
#endif
|
||||||
|
replace_buffer(tempfile_name);
|
||||||
|
|
||||||
|
|
||||||
/* Go back to the old position. */
|
/* Go back to the old position. */
|
||||||
goto_line_posx(lineno_save, current_x_save);
|
goto_line_posx(lineno_save, current_x_save);
|
||||||
|
|
Loading…
Reference in New Issue