diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 879cdecd0e3da51a030345b3f51e0410f70ab569..59c8617755584b786b827f0dcd899c9fb2f8434a 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -3,10 +3,11 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.106 2005/10/15 02:49:40 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.107 2006/02/11 21:55:35 momjian Exp $ */ #include "postgres_fe.h" #include "common.h" +#include "pqexpbuffer.h" #include "input.h" #include "print.h" #include "help.h" diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index 4272fcb2e50859a2449ffd32a6a9a2ae77ed651c..1b6e48cff3c24b1f9711d3b4abaeb7c860c512cb 100644 --- a/src/bin/psql/input.c +++ b/src/bin/psql/input.c @@ -3,12 +3,12 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/input.c,v 1.46 2005/10/15 02:49:40 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/input.c,v 1.47 2006/02/11 21:55:35 momjian Exp $ */ #include "postgres_fe.h" -#include "input.h" #include "pqexpbuffer.h" +#include "input.h" #include "settings.h" #include "tab-complete.h" #include "common.h" @@ -90,18 +90,55 @@ gets_interactive(const char *prompt) #ifdef USE_READLINE char *s; - static char *prev_hist = NULL; - if (useReadline) /* On some platforms, readline is declared as readline(char *) */ s = readline((char *) prompt); else s = gets_basic(prompt); - if (useHistory && s && s[0]) + return s; +#else + return gets_basic(prompt); +#endif +} + + +/* Put the line in the history buffer and also add the trailing \n */ +void pgadd_history(char *s, PQExpBuffer history_buf) +{ +#ifdef USE_READLINE + + int slen; + if (useReadline && useHistory && s && s[0]) { - enum histcontrol HC; + slen = strlen(s); + if (s[slen-1] == '\n') + appendPQExpBufferStr(history_buf, s); + else + { + appendPQExpBufferStr(history_buf, s); + appendPQExpBufferChar(history_buf, '\n'); + } + } +#endif +} + +/* Feed the contents of the history buffer to readline */ +void pgflush_history(PQExpBuffer history_buf) +{ +#ifdef USE_READLINE + char *s; + static char *prev_hist; + int slen, i; + + if (useReadline && useHistory ) + { + enum histcontrol HC; + + s = history_buf->data; + prev_hist = NULL; + HC = GetHistControlConfig(); if (((HC & hctl_ignorespace) && s[0] == ' ') || @@ -112,17 +149,27 @@ gets_interactive(const char *prompt) else { free(prev_hist); + slen = strlen(s); + /* Trim the trailing \n's */ + for (i = slen-1; i >= 0 && s[i] == '\n'; i--) + ; + s[i + 1] = '\0'; prev_hist = pg_strdup(s); add_history(s); } + + resetPQExpBuffer(history_buf); } - - return s; -#else - return gets_basic(prompt); #endif } +void pgclear_history(PQExpBuffer history_buf) +{ +#ifdef USE_READLINE + if (useReadline && useHistory) + resetPQExpBuffer(history_buf); +#endif +} /* @@ -157,6 +204,30 @@ gets_fromFile(FILE *source) } +static void encode_history() +{ + HIST_ENTRY *cur_hist; + char *cur_ptr; + + for (history_set_pos(0), cur_hist = current_history(); + cur_hist; cur_hist = next_history()) + for (cur_ptr = cur_hist->line; *cur_ptr; cur_ptr++) + if (*cur_ptr == '\n') + *cur_ptr = '\0'; +} + +static void decode_history() +{ + HIST_ENTRY *cur_hist; + char *cur_ptr; + + for (history_set_pos(0), cur_hist = current_history(); + cur_hist; cur_hist = next_history()) + for (cur_ptr = cur_hist->line; *cur_ptr; cur_ptr++) + if (*cur_ptr == '\0') + *cur_ptr = '\n'; +} + /* * Put any startup stuff related to input in here. It's good to maintain @@ -197,6 +268,8 @@ initializeInput(int flags) if (psql_history) read_history(psql_history); + + decode_history(); } #endif @@ -215,6 +288,7 @@ saveHistory(char *fname) #ifdef USE_READLINE if (useHistory && fname) { + encode_history(); if (write_history(fname) == 0) return true; diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h index bddc174b12a010bfd302988285c146aabe2ae87b..bd4ed99a2d871bf60007bfafee493a3fe72e3635 100644 --- a/src/bin/psql/input.h +++ b/src/bin/psql/input.h @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/input.h,v 1.23 2005/01/01 05:43:08 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/input.h,v 1.24 2006/02/11 21:55:35 momjian Exp $ */ #ifndef INPUT_H #define INPUT_H @@ -39,4 +39,9 @@ char *gets_fromFile(FILE *source); void initializeInput(int flags); bool saveHistory(char *fname); +void pgadd_history(char *s, PQExpBuffer history_buf); +void pgclear_history(PQExpBuffer history_buf); +void pgflush_history(PQExpBuffer history_buf); + + #endif /* INPUT_H */ diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index cebeda70c00e6383764721c027300fc3c770d66d..00b7969f18fce5ae2b11562c8b9ca9a24ee824a7 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/mainloop.c,v 1.69 2005/12/18 02:17:16 petere Exp $ + * $PostgreSQL: pgsql/src/bin/psql/mainloop.c,v 1.70 2006/02/11 21:55:35 momjian Exp $ */ #include "postgres_fe.h" #include "mainloop.h" @@ -37,6 +37,7 @@ MainLoop(FILE *source) PQExpBuffer query_buf; /* buffer for query being accumulated */ PQExpBuffer previous_buf; /* if there isn't anything in the new buffer * yet, use this one for \e, etc. */ + PQExpBuffer history_buf; char *line; /* current line of input */ int added_nl_pos; bool success; @@ -66,7 +67,9 @@ MainLoop(FILE *source) query_buf = createPQExpBuffer(); previous_buf = createPQExpBuffer(); - if (!query_buf || !previous_buf) + history_buf = createPQExpBuffer(); + + if (!query_buf || !previous_buf || !history_buf) { psql_error("out of memory\n"); exit(EXIT_FAILURE); @@ -90,7 +93,7 @@ MainLoop(FILE *source) successResult = EXIT_USER; break; } - + pgclear_history(history_buf); cancel_pressed = false; } @@ -106,6 +109,8 @@ MainLoop(FILE *source) count_eof = 0; slashCmdStatus = PSQL_CMD_UNKNOWN; prompt_status = PROMPT_READY; + if (pset.cur_cmd_interactive) + pgclear_history(history_buf); if (pset.cur_cmd_interactive) putc('\n', stdout); @@ -138,11 +143,15 @@ MainLoop(FILE *source) psql_scan_reset(scan_state); slashCmdStatus = PSQL_CMD_UNKNOWN; prompt_status = PROMPT_READY; + + if (pset.cur_cmd_interactive) + /* + * Pass all the contents of history_buf to readline + * and free the history buffer. + */ + pgflush_history(history_buf); } - - /* - * otherwise, get another line - */ + /* otherwise, get another line */ else if (pset.cur_cmd_interactive) { /* May need to reset prompt, eg after \r command */ @@ -212,7 +221,11 @@ MainLoop(FILE *source) */ psql_scan_setup(scan_state, line, strlen(line)); success = true; - + + if (pset.cur_cmd_interactive) + /* Put current line in the history buffer */ + pgadd_history(line, history_buf); + while (success || !die_on_error) { PsqlScanResult scan_result; @@ -287,6 +300,13 @@ MainLoop(FILE *source) scan_result == PSCAN_EOL) break; } + + if (pset.cur_cmd_interactive && prompt_status != PROMPT_CONTINUE) + /* + * Pass all the contents of history_buf to readline + * and free the history buffer. + */ + pgflush_history(history_buf); psql_scan_finish(scan_state); free(line); @@ -333,6 +353,7 @@ MainLoop(FILE *source) destroyPQExpBuffer(query_buf); destroyPQExpBuffer(previous_buf); + destroyPQExpBuffer(history_buf); psql_scan_destroy(scan_state); diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index 5afbfc68c49ae535326905a57448c4ac519036d1..f56ce6bf5bcc9dc82c26823859ca886eda9ce030 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/prompt.c,v 1.41 2006/01/03 23:32:30 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/psql/prompt.c,v 1.42 2006/02/11 21:55:35 momjian Exp $ */ #include "postgres_fe.h" #include "prompt.h" @@ -12,6 +12,7 @@ #include "settings.h" #include "common.h" +#include "pqexpbuffer.h" #include "input.h" #include "variables.h" diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 1a99dc9ca98d4ee602a433346a1752dac7665787..fd32a520fd47667d3752cb49a1ff821ddc95353e 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.144 2006/01/11 08:43:12 neilc Exp $ + * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.145 2006/02/11 21:55:35 momjian Exp $ */ /*---------------------------------------------------------------------- @@ -43,6 +43,7 @@ #include "postgres_fe.h" #include "tab-complete.h" +#include "pqexpbuffer.h" #include "input.h" /* If we don't have this, we might as well forget about the whole thing: */ @@ -50,7 +51,6 @@ #include #include "libpq-fe.h" -#include "pqexpbuffer.h" #include "common.h" #include "settings.h"