diff --git a/doc/nano.texi b/doc/nano.texi index aaed711d..828babf8 100644 --- a/doc/nano.texi +++ b/doc/nano.texi @@ -58,6 +58,9 @@ under the terms of either of the following licenses: @sp 5 You may contact the original author by e-mail: @email{chrisa@@asty.org} + +Or contact the current maintainer: @email{bensberg@@coevern.nl} + @sp 1 For suggesting improvements: @email{nano-devel@@gnu.org} @@ -719,6 +722,7 @@ With @kbd{M-X} the help lines. @end table +@sp 1 Option @code{-z} (@code{--suspendable}) has been removed. Suspension is enabled by default, reachable via @kbd{^T^Z}. (If you want a plain @kbd{^Z} to suspend nano, add @@ -734,6 +738,7 @@ or nanorc options. Each toggle can be flicked via a Meta-key combination --- the @kbd{Meta} key is normally the @kbd{Alt} key (@pxref{Commands} for more details). The following global toggles are available: +@sp 1 @table @code @item Constant Cursor Position Display @@ -1371,34 +1376,37 @@ is appropriate. Strange behavior can result when it is not. @sp 1 The format of @code{key} should be one of: -@itemize @w{} -@item -@code{^@var{X}} ------ where @var{X} is a Latin letter, or one of several +@indentedblock +@table @asis + +@item @code{^@var{X}} +where @var{X} is a Latin letter, or one of several ASCII characters (@@, ], \, ^, _), or the word "Space". Example: @code{^C}. -@item -@code{M-@var{X}} ------ where @var{X} is any ASCII character except [, -or the word "Space". +@item @code{M-@var{X}} +where @var{X} is any ASCII character except [, or the word "Space". Example: @code{M-8}. -@item -@code{Sh-M-@var{X}} ------ where @var{X} is a Latin letter. +@item @code{Sh-M-@var{X}} +where @var{X} is a Latin letter. Example: @code{Sh-M-U}. By default, each Meta+letter keystroke does the same as the corresponding Shift+Meta+letter. But when any Shift+Meta bind is made, that will no longer be the case, for all letters. -@item -@code{F@var{n}} ------ where @var{n} is a numeric value from 1 to 24. +@item @code{F@var{n}} +where @var{n} is a numeric value from 1 to 24. Example: @code{F10}. (Often, @code{F13} to @code{F24} can be typed as @code{F1} to @code{F12} with Shift.) -@item -@code{Ins} or @code{Del}. -@end itemize +@item @code{Ins} or @code{Del} +@end table +@end indentedblock + +@sp 1 Rebinding @code{^M} (Enter) or @code{^I} (Tab) is probably not a good idea. Rebinding @code{^[} (Esc) is not possible, because its keycode is the starter byte of Meta keystrokes and escape sequences. diff --git a/src/files.c b/src/files.c index 75256a96..fff462c3 100644 --- a/src/files.c +++ b/src/files.c @@ -970,12 +970,19 @@ char *get_next_filename(const char *name, const char *suffix) #ifndef NANO_TINY static pid_t pid_of_command = -1; /* The PID of a forked process -- needed when wanting to abort it. */ +static pid_t pid_of_sender = -1; + /* The PID of the process that pipes data to the above process. */ +static bool should_pipe = FALSE; + /* Whether we are piping data to the external command. */ /* Send an unconditional kill signal to the running external command. */ void cancel_the_command(int signal) { #ifdef SIGKILL - kill(pid_of_command, SIGKILL); + if (pid_of_command > 0) + kill(pid_of_command, SIGKILL); + if (should_pipe && pid_of_sender > 0) + kill(pid_of_sender, SIGKILL); #endif } @@ -1003,8 +1010,8 @@ void send_data(const linestruct *line, int fd) fclose(tube); } -/* Execute the given command in a shell. Return TRUE on success. */ -bool execute_command(const char *command) +/* Execute the given command in a shell. */ +void execute_command(const char *command) { #if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAIT) int from_fd[2], to_fd[2]; @@ -1012,14 +1019,16 @@ bool execute_command(const char *command) struct sigaction oldaction, newaction = {{0}}; /* Original and temporary handlers for SIGINT. */ ssize_t was_lineno = (openfile->mark ? 0 : openfile->current->lineno); - const bool should_pipe = (command[0] == '|'); + int command_status, sender_status; FILE *stream; + should_pipe = (command[0] == '|'); + /* Create a pipe to read the command's output from, and, if needed, * a pipe to feed the command's input through. */ if (pipe(from_fd) == -1 || (should_pipe && pipe(to_fd) == -1)) { statusline(ALERT, _("Could not create pipe: %s"), strerror(errno)); - return FALSE; + return; } /* Fork a child process to run the command in. */ @@ -1060,7 +1069,7 @@ bool execute_command(const char *command) if (pid_of_command == -1) { statusline(ALERT, _("Could not fork: %s"), strerror(errno)); close(from_fd[0]); - return FALSE; + return; } statusbar(_("Executing...")); @@ -1096,11 +1105,14 @@ bool execute_command(const char *command) } /* Create a separate process for piping the data to the command. */ - if (fork() == 0) { + if ((pid_of_sender = fork()) == 0) { send_data(whole_buffer ? openfile->filetop : cutbuffer, to_fd[1]); exit(0); } + if (pid_of_sender == -1) + statusline(ALERT, _("Could not fork: %s"), strerror(errno)); + close(to_fd[0]); close(to_fd[1]); @@ -1134,9 +1146,25 @@ bool execute_command(const char *command) } /* Wait for the external command (and possibly data sender) to terminate. */ - wait(NULL); - if (should_pipe) - wait(NULL); + waitpid(pid_of_command, &command_status, 0); + if (should_pipe && pid_of_sender > 0) + waitpid(pid_of_sender, &sender_status, 0); + + /* If the command failed, show what the shell reported. */ + if (WIFEXITED(command_status) == 0 || WEXITSTATUS(command_status)) + statusline(ALERT, WIFSIGNALED(command_status) ? _("Cancelled") : + _("Error: %s"), openfile->current->prev && + strstr(openfile->current->prev->data, ": ") ? + strstr(openfile->current->prev->data, ": ") + 2 : "---"); + else if (should_pipe && pid_of_sender > 0 && + (WIFEXITED(sender_status) == 0 || WEXITSTATUS(sender_status))) + statusline(ALERT, _("Piping failed")); + + /* If there was an error, undo and discard what the command did. */ + if (lastmessage == ALERT) { + do_undo(); + discard_until(openfile->current_undo); + } /* Restore the original handler for SIGINT. */ sigaction(SIGINT, &oldaction, NULL); @@ -1144,10 +1172,6 @@ bool execute_command(const char *command) /* Restore the terminal to its desired state, and disable * interpretation of the special control keys again. */ terminal_init(); - - return TRUE; -#else - return FALSE; #endif } #endif /* NANO_TINY */ @@ -2462,8 +2486,8 @@ char **username_completion(const char *morsel, size_t length, size_t *num_matche * This code is 'as is' with no warranty. * This code may safely be consumed by a BSD or GPL license. */ -/* Try to complete the given fragment of given length to a filename. */ -char **filename_completion(const char *morsel, size_t length, size_t *num_matches) +/* Try to complete the given fragment to an existing filename. */ +char **filename_completion(const char *morsel, size_t *num_matches) { char *dirname = copy_of(morsel); char *slash, *filename; @@ -2556,7 +2580,7 @@ char *input_tab(char *morsel, size_t *place, void (*refresh_func)(void), bool *l /* If there are no matches yet, try matching against filenames. */ if (matches == NULL) - matches = filename_completion(morsel, *place, &num_matches); + matches = filename_completion(morsel, &num_matches); /* If possible completions were listed before but none will be listed now... */ if (*listed && num_matches < 2) { diff --git a/src/nano.c b/src/nano.c index f784768f..c12770a3 100644 --- a/src/nano.c +++ b/src/nano.c @@ -2462,7 +2462,7 @@ int main(int argc, char **argv) searchstring = copy_of(&argv[optind][n + 1]); if (argv[optind][n] == '?') SET(BACKWARDS_SEARCH); - } else if (n == 1) + } else statusline(ALERT, _("Empty search string")); optind++; } else @@ -2500,6 +2500,7 @@ int main(int argc, char **argv) else if (lastmessage <= REMARK) wipe_statusbar(); openfile->placewewant = xplustabs(); + adjust_viewport(CENTERING); if (ISSET(USE_REGEXP)) tidy_up_after_search(); free(last_search);