commit 234bd9c9beda9a979c84a8f878c57593bd30026c
parent 0d9313763db17509238a8c9457c620182d383dd7
Author: David Lawrence Ramsey <pooka109@gmail.com>
Date: Thu, 9 Feb 2017 19:04:14 -0600
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.
Diffstat:
M | src/files.c | | | 33 | +++++++++++++++++++++++++++++++++ |
M | src/proto.h | | | 4 | ++++ |
M | src/text.c | | | 72 | +++++++++++++----------------------------------------------------------- |
3 files changed, 50 insertions(+), 59 deletions(-)
diff --git a/src/files.c b/src/files.c
@@ -545,6 +545,39 @@ void replace_buffer(const char *filename)
/* Put current at a place that is certain to exist. */
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 */
/* Update the screen to account for the current buffer. */
diff --git a/src/proto.h b/src/proto.h
@@ -294,6 +294,10 @@ void initialize_buffer_text(void);
bool open_buffer(const char *filename, bool undoable);
#ifndef DISABLE_SPELLER
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
void display_buffer(void);
#ifndef DISABLE_MULTIBUFFER
diff --git a/src/text.c b/src/text.c
@@ -2880,19 +2880,11 @@ const char *do_alt_speller(char *tempfile_name)
static int arglen = 3;
static char **spellargs = NULL;
#ifndef NANO_TINY
- bool old_mark_set = openfile->mark_set;
- bool added_magicline = FALSE;
- /* Whether we added a magicline after filebot. */
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 old_mark_set = openfile->mark_set;
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
/* Get the timestamp and the size of the temporary file. */
@@ -2904,9 +2896,8 @@ const char *do_alt_speller(char *tempfile_name)
return NULL;
#ifndef NANO_TINY
+ /* Save the mark's position and turn it off. */
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;
openfile->mark_set = FALSE;
}
@@ -2965,65 +2956,28 @@ const char *do_alt_speller(char *tempfile_name)
}
#ifndef NANO_TINY
+ /* Replace the text (or just the marked text) of the current buffer
+ * with the spell-checked text. */
if (old_mark_set) {
- /* Trim the filestruct so that it contains only the marked text. */
mark_order((const filestruct **)&top, &top_x,
(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
- * 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();
+ replace_marked_buffer(tempfile_name, top, top_x, bot, bot_x);
/* Adjust the end point of the marked region for any change in
* length of the region's last line. */
if (right_side_up)
- was_x = current_x_save;
- else
- was_x = openfile->mark_begin_x;
- if (top == bot)
- new_x = was_x - bot_x + top_x + strlen(openfile->filebot->data);
+ current_x_save = openfile->current_x;
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
- * 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);
+ openfile->mark_begin_x = openfile->current_x;
- /* 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. */
+ /* Restore the mark's position and turn it on. */
openfile->mark_begin = fsfromline(mb_lineno_save);
openfile->mark_set = TRUE;
- }
-#endif /* !NANO_TINY */
+ } else
+#endif
+ replace_buffer(tempfile_name);
+
/* Go back to the old position. */
goto_line_posx(lineno_save, current_x_save);