commit 35961c4252385b3b117d48951194c360116503cd
parent c2c5a51e5238cc5ab9419667db3bb15d565c519c
Author: David Lawrence Ramsey <pooka109@gmail.com>
Date: Fri, 23 Jan 2004 19:34:03 +0000
add the ability to spell-check only marked text when the mark is on
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1633 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Diffstat:
M | ChangeLog | | | 8 | ++++++++ |
M | TODO | | | 2 | +- |
M | src/files.c | | | 113 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
M | src/nano.c | | | 114 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
M | src/proto.h | | | 4 | ++++ |
5 files changed, 142 insertions(+), 99 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -9,7 +9,15 @@ CVS code -
NANO_NEXTLINE_KEY, and the help messages for them have been
changed accordingly. Also remove extraneous references to
NANO_DOWN_KEY in the search history shortcut entries. (DLR)
+- files.c:
+ write_marked()
+ - New function used to write the current marked selection to a
+ file, split out from do_writeout(). (DLR)
- nano.c:
+ do_spell(), do_int_speller(), do_alt_speller()
+ - Modify to write only the current selection from a file to the
+ temporary file used for spell checking when the mark is on,
+ and add a few miscellaneous cosmetic cleanups. (DLR)
main()
- Move the call to raw() on systems that don't define
_POSIX_VDISABLE outside the main input/output loop, as it
diff --git a/TODO b/TODO
@@ -8,7 +8,7 @@ For version 1.4:
- Rebindable keys?
- Keystroke to implement "Add next sequence as raw" like vi's ^V.
[DONE for edit window, needs to be done for statusbar prompt]
-- Spell check selected text only.
+- Spell check selected text only. [DONE]
- Make "To line" (^W^T) and "Read from Command" (^R^X) re-enter their
parent menu when their keystroke is entered a second time (^W^T^T and
(^R^X^X)(requires figuring out when to keep cursor pos and when not
diff --git a/src/files.c b/src/files.c
@@ -1672,6 +1672,69 @@ int write_file(const char *name, int tmp, int append, int nonamechange)
return retval;
}
+#ifndef NANO_SMALL
+/* Write a marked selection from a file out. First, set fileage and
+ * filebot as the top and bottom of the mark, respectively. Then call
+ * write_file() with the values of name, temp, append, and nonamechange.
+ * Finally, set fileage and filebot back to their old values and
+ * return. */
+int write_marked(const char *name, int tmp, int append, int
+ nonamechange)
+{
+ int retval = -1;
+ filestruct *fileagebak = fileage;
+ filestruct *filebotbak = filebot;
+ int oldmod = ISSET(MODIFIED);
+ /* write_file() unsets the MODIFIED flag. */
+ size_t topx;
+ /* The column of the beginning of the mark. */
+ char origchar;
+ /* We replace the character at the end of the mark with '\0'.
+ * We save the original character, to restore it. */
+ char *origcharloc;
+ /* The location of the character we nulled. */
+
+ if (!ISSET(MARK_ISSET))
+ return -1;
+
+ /* Set fileage as the top of the mark, and filebot as the bottom. */
+ if (current->lineno > mark_beginbuf->lineno ||
+ (current->lineno == mark_beginbuf->lineno &&
+ current_x > mark_beginx)) {
+ fileage = mark_beginbuf;
+ topx = mark_beginx;
+ filebot = current;
+ origcharloc = current->data + current_x;
+ } else {
+ fileage = current;
+ topx = current_x;
+ filebot = mark_beginbuf;
+ origcharloc = mark_beginbuf->data + mark_beginx;
+ }
+ origchar = *origcharloc;
+ *origcharloc = '\0';
+ fileage->data += topx;
+
+ /* If the line at filebot is blank, treat it as the magicline and
+ * hence the end of the file. Otherwise, treat the line after
+ * filebot as the end of the file. */
+ if (filebot->data[0] != '\0' && filebot->next != NULL)
+ filebot = filebot->next;
+
+ retval = write_file(name, tmp, append, nonamechange);
+
+ /* Now restore everything. */
+ fileage->data -= topx;
+ *origcharloc = origchar;
+ fileage = fileagebak;
+ filebot = filebotbak;
+ if (oldmod)
+ set_modified();
+
+ return retval;
+}
+#endif /* !NANO_SMALL */
+
int do_writeout(const char *path, int exiting, int append)
{
int i = 0;
@@ -1821,53 +1884,9 @@ int do_writeout(const char *path, int exiting, int append)
#ifndef NANO_SMALL
/* Here's where we allow the selected text to be written to
* a separate file. */
- if (ISSET(MARK_ISSET) && !exiting) {
- filestruct *fileagebak = fileage;
- filestruct *filebotbak = filebot;
- int oldmod = ISSET(MODIFIED);
- /* write_file() unsets the MODIFIED flag. */
- size_t topx;
- /* The column of the beginning of the mark. */
- char origchar;
- /* We replace the character at the end of the mark with
- * '\0'. We save the original character, to restore
- * it. */
- char *origcharloc;
- /* The location of the character we nulled. */
-
- /* Set fileage as the top of the mark, and filebot as the
- * bottom. */
- if (current->lineno > mark_beginbuf->lineno ||
- (current->lineno == mark_beginbuf->lineno &&
- current_x > mark_beginx)) {
- fileage = mark_beginbuf;
- topx = mark_beginx;
- filebot = current;
- origcharloc = current->data + current_x;
- } else {
- fileage = current;
- topx = current_x;
- filebot = mark_beginbuf;
- origcharloc = mark_beginbuf->data + mark_beginx;
- }
- origchar = *origcharloc;
- *origcharloc = '\0';
- fileage->data += topx;
- /* If the line at filebot is blank, treat it as the
- * magicline and hence the end of the file. Otherwise,
- * treat the line after filebot as the end of the file. */
- if (filebot->data[0] != '\0' && filebot->next != NULL)
- filebot = filebot->next;
- i = write_file(answer, 0, append, 1);
-
- /* Now restore everything. */
- fileage->data -= topx;
- *origcharloc = origchar;
- fileage = fileagebak;
- filebot = filebotbak;
- if (oldmod)
- set_modified();
- } else
+ if (ISSET(MARK_ISSET) && !exiting)
+ i = write_marked(answer, 0, append, 1);
+ else
#endif /* !NANO_SMALL */
i = write_file(answer, 0, append, 0);
diff --git a/src/nano.c b/src/nano.c
@@ -1632,21 +1632,20 @@ char *do_int_speller(char *tempfile_name)
pid_t pid_spell, pid_sort, pid_uniq;
int spell_status, sort_status, uniq_status;
- /* Create all three pipes up front */
-
+ /* Create all three pipes up front. */
if (pipe(spell_fd) == -1 || pipe(sort_fd) == -1 || pipe(uniq_fd) == -1)
return _("Could not create pipe");
statusbar(_("Creating misspelled word list, please wait..."));
- /* A new process to run spell in */
+ /* A new process to run spell in. */
if ((pid_spell = fork()) == 0) {
- /* Child continues, (i.e. future spell process) */
+ /* Child continues (i.e, future spell process). */
close(spell_fd[0]);
- /* replace the standard in with the tempfile */
+ /* Replace the standard input with the temp file. */
if ((tempfile_fd = open(tempfile_name, O_RDONLY)) == -1)
goto close_pipes_and_exit;
@@ -1655,88 +1654,89 @@ char *do_int_speller(char *tempfile_name)
close(tempfile_fd);
- /* send spell's standard out to the pipe */
+ /* Send spell's standard output to the pipe. */
if (dup2(spell_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
goto close_pipes_and_exit;
close(spell_fd[1]);
- /* Start spell program, we are using the PATH here!?!? */
+ /* Start spell program; we are using PATH. */
execlp("spell", "spell", NULL);
- /* Should not be reached, if spell is found!!! */
+ /* Should not be reached, if spell is found. */
exit(1);
}
- /* Parent continues here */
+ /* Parent continues here. */
close(spell_fd[1]);
- /* A new process to run sort in */
+ /* A new process to run sort in. */
if ((pid_sort = fork()) == 0) {
- /* Child continues, (i.e. future spell process) */
- /* replace the standard in with output of the old pipe */
+ /* Child continues (i.e, future spell process). Replace the
+ * standard input with the standard output of the old pipe. */
if (dup2(spell_fd[0], STDIN_FILENO) != STDIN_FILENO)
goto close_pipes_and_exit;
close(spell_fd[0]);
- /* send sort's standard out to the new pipe */
+ /* Send sort's standard output to the new pipe. */
if (dup2(sort_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
goto close_pipes_and_exit;
close(sort_fd[1]);
- /* Start sort program. Use -f to remove mixed case without having
- to have ANOTHER pipe for tr. If this isn't portable, let me know. */
+ /* Start sort program. Use -f to remove mixed case without
+ * having to have ANOTHER pipe for tr. If this isn't portable,
+ * let me know. */
execlp("sort", "sort", "-f", NULL);
- /* Should not be reached, if sort is found */
+ /* Should not be reached, if sort is found. */
exit(1);
}
close(spell_fd[0]);
close(sort_fd[1]);
- /* A new process to run uniq in */
+ /* A new process to run uniq in. */
if ((pid_uniq = fork()) == 0) {
- /* Child continues, (i.e. future uniq process) */
- /* replace the standard in with output of the old pipe */
+ /* Child continues (i.e, future uniq process). Replace the
+ * standard input with the standard output of the old pipe. */
if (dup2(sort_fd[0], STDIN_FILENO) != STDIN_FILENO)
goto close_pipes_and_exit;
close(sort_fd[0]);
- /* send uniq's standard out to the new pipe */
+ /* Send uniq's standard output to the new pipe. */
if (dup2(uniq_fd[1], STDOUT_FILENO) != STDOUT_FILENO)
goto close_pipes_and_exit;
close(uniq_fd[1]);
- /* Start uniq program, we are using PATH */
+ /* Start uniq program; we are using PATH. */
execlp("uniq", "uniq", NULL);
- /* Should not be reached, if uniq is found */
+ /* Should not be reached, if uniq is found. */
exit(1);
}
close(sort_fd[0]);
close(uniq_fd[1]);
- /* Child process was not forked successfully */
+ /* Child process was not forked successfully. */
if (pid_spell < 0 || pid_sort < 0 || pid_uniq < 0) {
close(uniq_fd[0]);
return _("Could not fork");
}
- /* Get system pipe buffer size */
+ /* Get system pipe buffer size. */
if ((pipe_buff_size = fpathconf(uniq_fd[0], _PC_PIPE_BUF)) < 1) {
close(uniq_fd[0]);
return _("Could not get size of pipe buffer");
}
- /* Read-in the returned spelling errors */
+ /* Read in the returned spelling errors. */
read_buff_read = 0;
read_buff_size = pipe_buff_size + 1;
read_buff = read_buff_ptr = charalloc(read_buff_size);
@@ -1752,7 +1752,7 @@ char *do_int_speller(char *tempfile_name)
*read_buff_ptr = (char)NULL;
close(uniq_fd[0]);
- /* Process the spelling errors */
+ /* Process the spelling errors. */
read_buff_word = read_buff_ptr = read_buff;
while (*read_buff_ptr != '\0') {
@@ -1770,7 +1770,7 @@ char *do_int_speller(char *tempfile_name)
read_buff_ptr++;
}
- /* special case where last word doesn't end with \n or \r */
+ /* Special case where last word doesn't end with \n or \r. */
if (read_buff_word != read_buff_ptr)
do_int_spell_fix(read_buff_word);
@@ -1778,8 +1778,7 @@ char *do_int_speller(char *tempfile_name)
replace_abort();
edit_refresh();
- /* Process end of spell process */
-
+ /* Process end of spell process. */
waitpid(pid_spell, &spell_status, 0);
waitpid(pid_sort, &sort_status, 0);
waitpid(pid_uniq, &uniq_status, 0);
@@ -1796,9 +1795,9 @@ char *do_int_speller(char *tempfile_name)
/* Otherwise... */
return NULL;
-close_pipes_and_exit:
+ close_pipes_and_exit:
- /* Don't leak any handles */
+ /* Don't leak any handles. */
close(tempfile_fd);
close(spell_fd[0]);
close(spell_fd[1]);
@@ -1823,9 +1822,9 @@ char *do_alt_speller(char *tempfile_name)
int mark_set = ISSET(MARK_ISSET);
int mbb_lineno_cur = 0;
/* We're going to close the current file, and open the output of
- the alternate spell command. The line that mark_beginbuf
- points to will be freed, so we save the line number and restore
- afterwards. */
+ * the alternate spell command. The line that mark_beginbuf
+ * points to will be freed, so we save the line number and
+ * restore afterwards. */
if (mark_set) {
mbb_lineno_cur = mark_beginbuf->lineno;
@@ -1835,7 +1834,7 @@ char *do_alt_speller(char *tempfile_name)
endwin();
- /* Set up an argument list to pass the execvp function */
+ /* Set up an argument list to pass execvp(). */
if (spellargs == NULL) {
spellargs = (char **)nmalloc(arglen * sizeof(char *));
@@ -1849,9 +1848,9 @@ char *do_alt_speller(char *tempfile_name)
}
spellargs[arglen - 2] = tempfile_name;
- /* Start a new process for the alternate speller */
+ /* Start a new process for the alternate speller. */
if ((pid_spell = fork()) == 0) {
- /* Start alternate spell program; we are using the PATH here!?!? */
+ /* Start alternate spell program; we are using PATH. */
execvp(spellargs[0], spellargs);
/* Should not be reached, if alternate speller is found!!! */
@@ -1862,9 +1861,9 @@ char *do_alt_speller(char *tempfile_name)
if (pid_spell < 0)
return _("Could not fork");
- /* Wait for alternate speller to complete */
-
+ /* Wait for alternate speller to complete. */
wait(&alt_spell_status);
+
if (!WIFEXITED(alt_spell_status) || WEXITSTATUS(alt_spell_status) != 0) {
char *altspell_error = NULL;
char *invoke_error = _("Could not invoke \"%s\"");
@@ -1876,22 +1875,27 @@ char *do_alt_speller(char *tempfile_name)
}
refresh();
- free_filestruct(fileage);
- global_init(1);
- open_file(tempfile_name, 0, 1);
-
#ifndef NANO_SMALL
+ if (!mark_set) {
+ /* Only reload the temp file if it isn't a marked selection. */
+#endif
+ free_filestruct(fileage);
+ global_init(1);
+ open_file(tempfile_name, 0, 1);
+#ifndef NANO_SMALL
+ }
+
if (mark_set) {
do_gotopos(mbb_lineno_cur, mark_beginx, y_cur, 0);
mark_beginbuf = current;
+ /* In case the line got shorter, assign mark_beginx. */
mark_beginx = current_x;
- /* In case the line got shorter, assign mark_beginx. */
SET(MARK_ISSET);
}
#endif
- /* go back to the old position, mark the file as modified, and make
- sure that the titlebar is refreshed */
+ /* Go back to the old position, mark the file as modified, and make
+ * sure that the titlebar is refreshed. */
do_gotopos(lineno_cur, x_cur, y_cur, pww_cur);
set_modified();
clearok(topwin, FALSE);
@@ -1905,8 +1909,9 @@ int do_spell(void)
{
#ifdef DISABLE_SPELLER
nano_disabled_msg();
- return TRUE;
+ return 1;
#else
+ int i;
char *temp, *spell_msg;
if ((temp = safe_tempnam(0, "nano.")) == NULL) {
@@ -1915,15 +1920,22 @@ int do_spell(void)
return 0;
}
- if (write_file(temp, 1, 0, 0) == -1) {
+#ifndef NANO_SMALL
+ if (ISSET(MARK_ISSET))
+ i = write_marked(temp, 1, 0, 0);
+ else
+#endif
+ i = write_file(temp, 1, 0, 0);
+
+ if (i == -1) {
statusbar(_("Spell checking failed: unable to write temp file!"));
free(temp);
return 0;
}
#ifdef ENABLE_MULTIBUFFER
- /* update the current open_files entry before spell-checking, in case
- any problems occur */
+ /* Update the current open_files entry before spell-checking, in
+ * case any problems occur. */
add_open_file(1);
#endif
@@ -1931,7 +1943,7 @@ int do_spell(void)
spell_msg = do_alt_speller(temp);
else
spell_msg = do_int_speller(temp);
- remove(temp);
+ unlink(temp);
free(temp);
if (spell_msg != NULL) {
diff --git a/src/proto.h b/src/proto.h
@@ -179,6 +179,10 @@ void init_operating_dir(void);
int check_operating_dir(const char *currpath, int allow_tabcomp);
#endif
int write_file(const char *name, int tmp, int append, int nonamechange);
+#ifndef NANO_SMALL
+int write_marked(const char *name, int tmp, int append, int
+ nonamechange);
+#endif
int do_writeout(const char *path, int exiting, int append);
int do_writeout_void(void);
char *real_dir_from_tilde(const char *buf);