On Thu, Jan 7, 2016 at 9:32 PM, Chet Ramey <chet.ra...@case.edu> wrote: > On 1/5/16 8:08 AM, Greg Wooledge wrote: > >> imadev:~$ zap me >> bash: zap: command not found >> imadev:~$ history -d -1 >> bash: history: -1: history position out of range >> imadev:~$ history -d end >> bash: history: end: history position out of range >> [..] > > Yes, this is a reasonable feature to consider for a future version.
I cant believe we do not have it already. Maybe I am missing something, please review the following (works for me; devel at 6f82653c5ef09aeeeba4376a1c65ce86c3605c00, also in attachment in case of formatting problems): diff --git a/builtins/history.def b/builtins/history.def index dfa4fb7..4c938af 100644 --- a/builtins/history.def +++ b/builtins/history.def @@ -107,6 +107,8 @@ history_builtin (list) int flags, opt, result, old_history_lines, obase; char *filename, *delete_arg; intmax_t delete_offset; + int is_legal_number = 0; + int index = 0; flags = 0; reset_internal_getopt (); @@ -180,14 +182,34 @@ history_builtin (list) #endif else if (flags & DFLAG) { - if ((legal_number (delete_arg, &delete_offset) == 0) - || (delete_offset < history_base) + is_legal_number = legal_number (delete_arg, &delete_offset); + if (is_legal_number == 0) + { + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + if ((delete_arg[0] == '-') && (delete_offset < 0)) + { + if ((index = history_length + delete_offset) >= 0) + { + opt = index + 1; + } + else + { + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + } + else + { + if ((delete_offset < history_base) || (delete_offset > (history_base + history_length))) { sh_erange (delete_arg, _("history position")); return (EXECUTION_FAILURE); } opt = delete_offset; + } result = bash_delete_histent (opt - history_base); /* Since remove_history changes history_length, this can happen if we delete the last history entry. */ sincerely, pg
diff --git a/builtins/history.def b/builtins/history.def index dfa4fb7..4c938af 100644 --- a/builtins/history.def +++ b/builtins/history.def @@ -107,6 +107,8 @@ history_builtin (list) int flags, opt, result, old_history_lines, obase; char *filename, *delete_arg; intmax_t delete_offset; + int is_legal_number = 0; + int index = 0; flags = 0; reset_internal_getopt (); @@ -180,14 +182,34 @@ history_builtin (list) #endif else if (flags & DFLAG) { - if ((legal_number (delete_arg, &delete_offset) == 0) - || (delete_offset < history_base) + is_legal_number = legal_number (delete_arg, &delete_offset); + if (is_legal_number == 0) + { + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + if ((delete_arg[0] == '-') && (delete_offset < 0)) + { + if ((index = history_length + delete_offset) >= 0) + { + opt = index + 1; + } + else + { + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + } + else + { + if ((delete_offset < history_base) || (delete_offset > (history_base + history_length))) { sh_erange (delete_arg, _("history position")); return (EXECUTION_FAILURE); } opt = delete_offset; + } result = bash_delete_histent (opt - history_base); /* Since remove_history changes history_length, this can happen if we delete the last history entry. */