Thread: psql: customizable readline history filename
Hi, the following patch makes the filename used to store the readline history customizable through a variable named HISTFILE, analogous to psql's already implemented HISTCONTROL and HISTSIZE variables, and bash's HISTFILE-Variable. The motivation was to be able to get psql to maintain separate histories for separate databases. This is now easily achievable through a line like the following in ~/.psqlrc: \set HISTFILE ~/.psql_history- :DBNAME regards, Andreas Index: doc/src/sgml/ref/psql-ref.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v retrieving revision 1.123 diff -c -r1.123 psql-ref.sgml *** doc/src/sgml/ref/psql-ref.sgml 6 Oct 2004 18:39:15 -0000 1.123 --- doc/src/sgml/ref/psql-ref.sgml 26 Oct 2004 05:57:57 -0000 *************** *** 1973,1978 **** --- 1973,2001 ---- </varlistentry> <varlistentry> + <term><varname>HISTFILE</varname></term> + <listitem> + <para> + This variable contains the filename used to save the history. + Its default value is <filename>~/.psql_history</filename>. + When unset or empty, the command history is not saved upon + program termination. For example, + <programlisting> + \set HISTFILE ~/.psql_history- :DBNAME + </programlisting> + in your <filename>~/.psqlrc</filename> will get psql to + maintain a separate history for each database. + </para> + <note> + <para> + This feature was shamelessly plagiarized from + <application>Bash</application>. + </para> + </note> + </listitem> + </varlistentry> + + <varlistentry> <term><varname>HISTSIZE</varname></term> <listitem> <para> Index: src/bin/psql/input.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.c,v retrieving revision 1.41 diff -c -r1.41 input.c *** src/bin/psql/input.c 12 Oct 2004 21:54:44 -0000 1.41 --- src/bin/psql/input.c 26 Oct 2004 05:57:57 -0000 *************** *** 38,46 **** static void finishInput(int, void *); #endif - #define PSQLHISTORY ".psql_history" - - #ifdef USE_READLINE static enum histcontrol GetHistControlConfig(void) --- 38,43 ---- *************** *** 167,173 **** #ifdef USE_READLINE if (flags & 1) { ! char home[MAXPGPATH]; useReadline = true; initialize_readline(); --- 164,171 ---- #ifdef USE_READLINE if (flags & 1) { ! const char *psql_history; ! char *tilde_expanded; useReadline = true; initialize_readline(); *************** *** 176,191 **** if (GetVariable(pset.vars, "HISTSIZE") == NULL) SetVariable(pset.vars, "HISTSIZE", "500"); using_history(); - if (get_home_path(home)) - { - char *psql_history; ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); ! read_history(psql_history); ! free(psql_history); ! } } #endif --- 174,189 ---- if (GetVariable(pset.vars, "HISTSIZE") == NULL) SetVariable(pset.vars, "HISTSIZE", "500"); using_history(); ! if (GetVariable(pset.vars, "HISTFILE") == NULL) ! SetVariable(pset.vars, "HISTFILE", "~/.psql_history"); ! ! psql_history = GetVariable(pset.vars, "HISTFILE"); ! ! tilde_expanded = pg_strdup(psql_history); ! expand_tilde(&tilde_expanded); ! read_history(tilde_expanded); ! free(tilde_expanded); } #endif *************** *** 228,252 **** #ifdef USE_READLINE if (useHistory) { ! char home[MAXPGPATH]; ! ! if (get_home_path(home)) ! { ! char *psql_history; ! int hist_size; ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); ! if (hist_size >= 0) ! stifle_history(hist_size); ! ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); ! write_history(psql_history); ! free(psql_history); ! } } #endif } --- 226,251 ---- #ifdef USE_READLINE if (useHistory) { ! const char *psql_history; ! char *tilde_expanded; ! int hist_size; ! ! psql_history = GetVariable(pset.vars, "HISTFILE"); ! ! if (!psql_history || !strlen(psql_history)) ! return; ! ! tilde_expanded = pg_strdup(psql_history); ! expand_tilde(&tilde_expanded); ! ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); ! if (hist_size >= 0) ! stifle_history(hist_size); ! saveHistory(tilde_expanded); ! free(tilde_expanded); } #endif }
This has been saved for the 8.1 release: http:/momjian.postgresql.org/cgi-bin/pgpatches2 --------------------------------------------------------------------------- Andreas Seltenreich wrote: > Hi, > > the following patch makes the filename used to store the readline > history customizable through a variable named HISTFILE, analogous to > psql's already implemented HISTCONTROL and HISTSIZE variables, and > bash's HISTFILE-Variable. > > The motivation was to be able to get psql to maintain separate > histories for separate databases. This is now easily achievable > through a line like the following in ~/.psqlrc: > > \set HISTFILE ~/.psql_history- :DBNAME > > regards, > Andreas > > Index: doc/src/sgml/ref/psql-ref.sgml > =================================================================== > RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v > retrieving revision 1.123 > diff -c -r1.123 psql-ref.sgml > *** doc/src/sgml/ref/psql-ref.sgml 6 Oct 2004 18:39:15 -0000 1.123 > --- doc/src/sgml/ref/psql-ref.sgml 26 Oct 2004 05:57:57 -0000 > *************** > *** 1973,1978 **** > --- 1973,2001 ---- > </varlistentry> > > <varlistentry> > + <term><varname>HISTFILE</varname></term> > + <listitem> > + <para> > + This variable contains the filename used to save the history. > + Its default value is <filename>~/.psql_history</filename>. > + When unset or empty, the command history is not saved upon > + program termination. For example, > + <programlisting> > + \set HISTFILE ~/.psql_history- :DBNAME > + </programlisting> > + in your <filename>~/.psqlrc</filename> will get psql to > + maintain a separate history for each database. > + </para> > + <note> > + <para> > + This feature was shamelessly plagiarized from > + <application>Bash</application>. > + </para> > + </note> > + </listitem> > + </varlistentry> > + > + <varlistentry> > <term><varname>HISTSIZE</varname></term> > <listitem> > <para> > Index: src/bin/psql/input.c > =================================================================== > RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.c,v > retrieving revision 1.41 > diff -c -r1.41 input.c > *** src/bin/psql/input.c 12 Oct 2004 21:54:44 -0000 1.41 > --- src/bin/psql/input.c 26 Oct 2004 05:57:57 -0000 > *************** > *** 38,46 **** > static void finishInput(int, void *); > #endif > > - #define PSQLHISTORY ".psql_history" > - > - > #ifdef USE_READLINE > static enum histcontrol > GetHistControlConfig(void) > --- 38,43 ---- > *************** > *** 167,173 **** > #ifdef USE_READLINE > if (flags & 1) > { > ! char home[MAXPGPATH]; > > useReadline = true; > initialize_readline(); > --- 164,171 ---- > #ifdef USE_READLINE > if (flags & 1) > { > ! const char *psql_history; > ! char *tilde_expanded; > > useReadline = true; > initialize_readline(); > *************** > *** 176,191 **** > if (GetVariable(pset.vars, "HISTSIZE") == NULL) > SetVariable(pset.vars, "HISTSIZE", "500"); > using_history(); > - if (get_home_path(home)) > - { > - char *psql_history; > > ! psql_history = pg_malloc(strlen(home) + 1 + > ! strlen(PSQLHISTORY) + 1); > ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); > ! read_history(psql_history); > ! free(psql_history); > ! } > } > #endif > > --- 174,189 ---- > if (GetVariable(pset.vars, "HISTSIZE") == NULL) > SetVariable(pset.vars, "HISTSIZE", "500"); > using_history(); > > ! if (GetVariable(pset.vars, "HISTFILE") == NULL) > ! SetVariable(pset.vars, "HISTFILE", "~/.psql_history"); > ! > ! psql_history = GetVariable(pset.vars, "HISTFILE"); > ! > ! tilde_expanded = pg_strdup(psql_history); > ! expand_tilde(&tilde_expanded); > ! read_history(tilde_expanded); > ! free(tilde_expanded); > } > #endif > > *************** > *** 228,252 **** > #ifdef USE_READLINE > if (useHistory) > { > ! char home[MAXPGPATH]; > ! > ! if (get_home_path(home)) > ! { > ! char *psql_history; > ! int hist_size; > > ! psql_history = pg_malloc(strlen(home) + 1 + > ! strlen(PSQLHISTORY) + 1); > > ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); > > ! if (hist_size >= 0) > ! stifle_history(hist_size); > ! > ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); > ! write_history(psql_history); > ! free(psql_history); > ! } > } > #endif > } > --- 226,251 ---- > #ifdef USE_READLINE > if (useHistory) > { > ! const char *psql_history; > ! char *tilde_expanded; > ! int hist_size; > ! > ! psql_history = GetVariable(pset.vars, "HISTFILE"); > ! > ! if (!psql_history || !strlen(psql_history)) > ! return; > ! > ! tilde_expanded = pg_strdup(psql_history); > ! expand_tilde(&tilde_expanded); > ! > ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); > > ! if (hist_size >= 0) > ! stifle_history(hist_size); > > ! saveHistory(tilde_expanded); > > ! free(tilde_expanded); > } > #endif > } > > ---------------------------(end of broadcast)--------------------------- > TIP 7: don't forget to increase your free space map settings -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073
Andreas Seltenreich wrote: > Hi, > > the following patch makes the filename used to store the readline > history customizable through a variable named HISTFILE, analogous to > psql's already implemented HISTCONTROL and HISTSIZE variables, and > bash's HISTFILE-Variable. > > The motivation was to be able to get psql to maintain separate > histories for separate databases. This is now easily achievable > through a line like the following in ~/.psqlrc: > > \set HISTFILE ~/.psql_history- :DBNAME I have applied your patch with slight modifications; new version attached. Win32 doesn't have tilde expansion, so your idea of using "~/.psql_history" as a default would not work --- I had to keep the get_home_path() code in there. I decided to make psql_history a file static variable, so we would not have to recompute its value when writing the history file. I noticed your documentation example had a space before :DBNAME --- I removed the space. You had the idea of not saving the history on exit if HISTFILE is not set. I don't think we have community agreement on that change, and I bet we wouldn't get it. (I have removed your documentation mention of this.) I think setting HISTSIZE to zero has that effect already if people want it. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: doc/src/sgml/ref/psql-ref.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v retrieving revision 1.139 diff -c -c -r1.139 psql-ref.sgml *** doc/src/sgml/ref/psql-ref.sgml 9 Jun 2005 15:27:26 -0000 1.139 --- doc/src/sgml/ref/psql-ref.sgml 10 Jun 2005 15:33:22 -0000 *************** *** 1988,1993 **** --- 1988,2015 ---- </varlistentry> <varlistentry> + <term><varname>HISTFILE</varname></term> + <listitem> + <para> + This variable contains the filename used to save the history. + Its default value is <filename>~/.psql_history</filename>. + For example, use: + <programlisting> + \set HISTFILE ~/.psql_history-:DBNAME + </programlisting> + in your <filename>~/.psqlrc</filename> will get psql to + maintain a separate history for each database. + </para> + <note> + <para> + This feature was shamelessly plagiarized from + <application>Bash</application>. + </para> + </note> + </listitem> + </varlistentry> + + <varlistentry> <term><varname>HISTSIZE</varname></term> <listitem> <para> Index: src/bin/psql/input.c =================================================================== RCS file: /cvsroot/pgsql/src/bin/psql/input.c,v retrieving revision 1.43 diff -c -c -r1.43 input.c *** src/bin/psql/input.c 6 Jan 2005 18:29:09 -0000 1.43 --- src/bin/psql/input.c 10 Jun 2005 15:33:23 -0000 *************** *** 24,29 **** --- 24,31 ---- #ifdef USE_READLINE static bool useReadline; static bool useHistory; + char *psql_history; + enum histcontrol { *************** *** 177,192 **** if (GetVariable(pset.vars, "HISTSIZE") == NULL) SetVariable(pset.vars, "HISTSIZE", "500"); using_history(); ! if (get_home_path(home)) { ! char *psql_history; ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); read_history(psql_history); - free(psql_history); - } } #endif --- 179,202 ---- if (GetVariable(pset.vars, "HISTSIZE") == NULL) SetVariable(pset.vars, "HISTSIZE", "500"); using_history(); ! ! if (GetVariable(pset.vars, "HISTFILE") == NULL) ! { ! if (get_home_path(home)) ! { ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! snprintf(psql_history, MAXPGPATH, "%s/%s", home, PSQLHISTORY); ! } ! } ! else { ! psql_history = pg_strdup(GetVariable(pset.vars, "HISTFILE")); ! expand_tilde(&psql_history); ! } ! if (psql_history) read_history(psql_history); } #endif *************** *** 227,251 **** #endif { #ifdef USE_READLINE ! if (useHistory) { ! char home[MAXPGPATH]; ! if (get_home_path(home)) ! { ! char *psql_history; ! int hist_size; ! ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); ! if (hist_size >= 0) ! stifle_history(hist_size); ! ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); ! write_history(psql_history); ! free(psql_history); ! } } #endif } --- 237,253 ---- #endif { #ifdef USE_READLINE ! if (useHistory && psql_history) { ! int hist_size; ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); ! if (hist_size >= 0) ! stifle_history(hist_size); ! ! saveHistory(psql_history); ! free(psql_history); ! psql_history = NULL; } #endif }
Bruce Momjian schrob: > I noticed your documentation example had a space before :DBNAME --- I > removed the space. This space is necessary for proper expansion of the parameter. The \set-Command concatenates all its arguments after expansion: --8<---------------cut here---------------start------------->8--- scratch=# \set HISTFILE .psql_history-:DBNAME scratch=# \echo :HISTFILE .psql_history-:DBNAME scratch=# \set HISTFILE .psql_history- :DBNAME scratch=# \echo :HISTFILE .psql_history-scratch scratch=# --8<---------------cut here---------------end--------------->8--- > You had the idea of not saving the history on exit if HISTFILE is not > set. I don't think we have community agreement on that change, and I > bet we wouldn't get it. (I have removed your documentation mention of > this.) I think setting HISTSIZE to zero has that effect already if > people want it. I went for bash's behaviour back then, since we copied bash's semantics with the other history options too. Thanks! Andreas
Andreas Seltenreich wrote: > Bruce Momjian schrob: > > > I noticed your documentation example had a space before :DBNAME --- I > > removed the space. > > This space is necessary for proper expansion of the parameter. The > \set-Command concatenates all its arguments after expansion: > > --8<---------------cut here---------------start------------->8--- > scratch=# \set HISTFILE .psql_history-:DBNAME > scratch=# \echo :HISTFILE > .psql_history-:DBNAME > scratch=# \set HISTFILE .psql_history- :DBNAME > scratch=# \echo :HISTFILE > .psql_history-scratch > scratch=# > --8<---------------cut here---------------end--------------->8--- > > > You had the idea of not saving the history on exit if HISTFILE is not > > set. I don't think we have community agreement on that change, and I > > bet we wouldn't get it. (I have removed your documentation mention of > > this.) I think setting HISTSIZE to zero has that effect already if > > people want it. > > I went for bash's behaviour back then, since we copied bash's > semantics with the other history options too. Ah, I see. I tested ':' expansion in queries and found the space wasn't needed, but I see now that with \set it is needed: test=> \set x a test=> \echo :x a test=> \set y b:x test=> \echo :y b:x test=> \set y b :x test=> \echo :y ba I will update the documentation to add the space. Thanks. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073