diff -ru bash-3.0.16/bashhist.c bash-3.0-patched/bashhist.c --- bash-3.0.16/bashhist.c 2004-03-22 14:27:59.000000000 +0100 +++ bash-3.0-patched/bashhist.c 2007-04-28 19:39:17.000000000 +0200 @@ -586,10 +586,12 @@ LITERAL_HISTORY is set, we're saving lines in the history with embedded newlines, so it's OK to save comment lines. We also make sure to save multiple-line quoted strings or other constructs. */ +extern void ar_accept_new_line(void); void maybe_add_history (line) char *line; { + ar_accept_new_line(); hist_last_line_added = 0; /* Don't use the value of history_control to affect the second diff -ru bash-3.0.16/bashline.c bash-3.0-patched/bashline.c --- bash-3.0.16/bashline.c 2004-09-08 17:08:17.000000000 +0200 +++ bash-3.0-patched/bashline.c 2006-07-10 00:34:23.000000000 +0200 @@ -203,6 +203,8 @@ static int bash_vi_complete __P((int, int)); #endif static int emacs_edit_and_execute_command __P((int, int)); +static int ar_dirhistory_prev __P((int, int)); +static int ar_dirhistory_next __P((int, int)); /* Non-zero once initalize_readline () has been called. */ int bash_readline_initialized = 0; @@ -472,6 +474,10 @@ rl_bind_key_in_map ('=', bash_vi_complete, vi_movement_keymap); #endif + // -AR- + rl_bind_keyseq ("\\e[5~", ar_dirhistory_prev); + rl_bind_keyseq ("\\e[6~", ar_dirhistory_next); + rl_completer_quote_characters = "'\""; /* This sets rl_completer_word_break_characters and rl_special_prefixes @@ -866,6 +872,39 @@ return (edit_and_execute_command (count, c, EMACS_EDITING_MODE, EMACS_EDIT_COMMAND)); } +extern int _rl_last_v_pos; /* optional */ + +static void ar_redisplay_prompt(void) +{ + _rl_erase_entire_line(); /* */ + _rl_move_vert(_rl_last_v_pos-1); /* optional */ + _rl_last_v_pos++; /* */ + + bash_re_edit(rl_line_buffer); + rl_point = rl_end; + rl_delete_text(0, rl_point); + rl_point = rl_end = rl_mark = 0; + rl_newline(1, '\n'); +} + +static int +ar_dirhistory_prev (count, c) + int count, c; +{ + if (cd_builtin_ar_dirhist_prev() == EXECUTION_SUCCESS) + ar_redisplay_prompt(); + return 0; +} + +static int +ar_dirhistory_next (count, c) + int count, c; +{ + if (cd_builtin_ar_dirhist_next() == EXECUTION_SUCCESS) + ar_redisplay_prompt(); + return 0; +} + #if defined (ALIAS) static int posix_edit_macros (count, key) diff -ru bash-3.0.16/builtins/cd.def bash-3.0-patched/builtins/cd.def --- bash-3.0.16/builtins/cd.def 2004-05-13 17:08:45.000000000 +0200 +++ bash-3.0-patched/builtins/cd.def 2007-04-28 19:52:22.000000000 +0200 @@ -139,6 +139,85 @@ #define LCD_PRINTPATH 0x004 #define LCD_FREEDIRNAME 0x010 +// -AR- +#define AR_DIRHIST_MAX 42 +static char *ar_dirhist[AR_DIRHIST_MAX]; +static int ar_dirhist_tot = 0; +static int ar_dirhist_cur = 0; + +void +ar_accept_new_line (void) +{ + char *pwdvar = get_string_value ("PWD"); + if (pwdvar) + { + if (ar_dirhist_tot && !strcmp(pwdvar, ar_dirhist[ar_dirhist_tot-1])) + /* already in history */; + else + { + if (ar_dirhist_tot == AR_DIRHIST_MAX) + { + int i; + FREE(ar_dirhist[0]); + for (i=1; i 0) + ar_dirhist_cur = ar_dirhist_tot - 1; + } + return ar_dirhist_cur < ar_dirhist_tot; +} + +int +cd_builtin_ar_dirhist_prev (void) +{ + WORD_LIST *tlist; + + if (ar_dirhist_normalize() && ar_dirhist_cur > 0) + { + ar_dirhist_cur--; + tlist = make_word_list (make_word (ar_dirhist[ar_dirhist_cur]), NULL); + cd_builtin (tlist); + dispose_words (tlist); + return EXECUTION_SUCCESS; + } + else + return EXECUTION_FAILURE; +} + +int +cd_builtin_ar_dirhist_next (void) +{ + WORD_LIST *tlist; + + if (ar_dirhist_normalize() && ar_dirhist_cur < ar_dirhist_tot-1) + { + ar_dirhist_cur++; + tlist = make_word_list (make_word (ar_dirhist[ar_dirhist_cur]), NULL); + cd_builtin (tlist); + dispose_words (tlist); + return EXECUTION_SUCCESS; + } + else + return EXECUTION_FAILURE; +} +// -AR- + + /* This builtin is ultimately the way that all user-visible commands should change the current working directory. It is called by cd_to_string (), so the programming interface is simple, and it handles errors and