From: David Lawrence Ramsey Date: Fri, 23 Jan 2004 19:34:03 +0000 (+0000) Subject: add the ability to spell-check only marked text when the mark is on X-Git-Tag: v1.3.2~65 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=35961c4252385b3b117d48951194c360116503cd;p=nano.git 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 --- diff --git a/ChangeLog b/ChangeLog index 8bef8ac0..7e933e05 100644 --- 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 index 9ae8054f..f034ccb0 100644 --- 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 index 5221f26f..2bcff96a 100644 --- 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 index a766d68d..5e012c85 100644 --- 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 index 12ae7928..808b4b07 100644 --- 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);