mirror of git://git.sv.gnu.org/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
This commit is contained in:
parent
c2c5a51e52
commit
35961c4252
|
@ -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
|
||||
|
|
2
TODO
2
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
|
||||
|
|
113
src/files.c
113
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);
|
||||
|
||||
|
|
114
src/nano.c
114
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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue