On Wed, 7 Dec 2005, Andrew Dunstan wrote: > Sergey E. Koposov wrote: > > >I also wanted this feature for a long time. > >And I agree that it is rather simple to just remove the \n when writing to > >the > >readline history file, but I don't think that's what everybody wants. I > >think that people want to preserve the original formatting... > > > >So in that case the solution can be just putting some symbol instead of \n > >in the history file, and during the loading of that file replace it back > >(that symbol can be zero byte for example). But I'm not sure that people > >will like that solution too. > > > A zero byte is probably a pretty bad choice. Some other low valued byte > (e.g. \x01 ) would probably work better. > > And I agree that format preservation is highly desirable.
If actually the idea with just replacing '\n' in the history with other byte is not rejected I'm sending the new version of the psql patch including also the saving of the multiline queries in the history (even after exiting the psql). Currently I replace '\n' with the '\x01' as Andrew suggested. Regards, Sergey ***************************************************** Sergey E. Koposov Max-Planck Institut for Astronomy Web: http://lnfm1.sai.msu.ru/~math E-mail: [EMAIL PROTECTED]
Index: help.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/help.c,v retrieving revision 1.106 diff -c -r1.106 help.c *** help.c 15 Oct 2005 02:49:40 -0000 1.106 --- help.c 8 Dec 2005 04:04:17 -0000 *************** *** 7,12 **** --- 7,13 ---- */ #include "postgres_fe.h" #include "common.h" + #include "pqexpbuffer.h" #include "input.h" #include "print.h" #include "help.h" Index: input.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.c,v retrieving revision 1.46 diff -c -r1.46 input.c *** input.c 15 Oct 2005 02:49:40 -0000 1.46 --- input.c 8 Dec 2005 04:04:17 -0000 *************** *** 7,14 **** */ #include "postgres_fe.h" - #include "input.h" #include "pqexpbuffer.h" #include "settings.h" #include "tab-complete.h" #include "common.h" --- 7,14 ---- */ #include "postgres_fe.h" #include "pqexpbuffer.h" + #include "input.h" #include "settings.h" #include "tab-complete.h" #include "common.h" *************** *** 90,107 **** #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]) { - enum histcontrol HC; HC = GetHistControlConfig(); if (((HC & hctl_ignorespace) && s[0] == ' ') || --- 90,146 ---- #ifdef USE_READLINE char *s; if (useReadline) /* On some platforms, readline is declared as readline(char *) */ s = readline((char *) prompt); else s = gets_basic(prompt); ! 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]) ! { ! 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,130 **** else { free(prev_hist); prev_hist = pg_strdup(s); add_history(s); } } - return s; - #else - return gets_basic(prompt); #endif } /* * gets_fromFile * --- 151,184 ---- 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); + } + #endif + } + + void pgclear_history(PQExpBuffer history_buf) + { + #ifdef USE_READLINE + if (useReadline && useHistory ) + { + resetPQExpBuffer(history_buf); } #endif } + + /* * gets_fromFile * *************** *** 158,163 **** --- 212,255 ---- + + 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 = (char)1; + } + } + } + } + + 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==(char)1) + { + *cur_ptr = '\n'; + } + } + } + } + + + + /* * Put any startup stuff related to input in here. It's good to maintain * abstraction this way. *************** *** 197,202 **** --- 289,296 ---- if (psql_history) read_history(psql_history); + + decode_history(); } #endif *************** *** 215,220 **** --- 309,315 ---- #ifdef USE_READLINE if (useHistory && fname) { + encode_history(); if (write_history(fname) == 0) return true; Index: input.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.h,v retrieving revision 1.23 diff -c -r1.23 input.h *** input.h 1 Jan 2005 05:43:08 -0000 1.23 --- input.h 8 Dec 2005 04:04:17 -0000 *************** *** 39,42 **** --- 39,47 ---- 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 */ Index: mainloop.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/mainloop.c,v retrieving revision 1.68 diff -c -r1.68 mainloop.c *** mainloop.c 15 Oct 2005 02:49:40 -0000 1.68 --- mainloop.c 8 Dec 2005 04:04:18 -0000 *************** *** 37,42 **** --- 37,43 ---- 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,72 **** query_buf = createPQExpBuffer(); previous_buf = createPQExpBuffer(); ! if (!query_buf || !previous_buf) { psql_error("out of memory\n"); exit(EXIT_FAILURE); --- 67,75 ---- query_buf = createPQExpBuffer(); previous_buf = createPQExpBuffer(); ! history_buf = createPQExpBuffer(); ! ! if (!query_buf || !previous_buf || !history_buf) { psql_error("out of memory\n"); exit(EXIT_FAILURE); *************** *** 90,95 **** --- 93,101 ---- successResult = EXIT_USER; break; } + { + pgclear_history(history_buf); + } cancel_pressed = false; } *************** *** 100,111 **** --- 106,120 ---- /* got here with longjmp */ /* reset parsing state */ + resetPQExpBuffer(query_buf); psql_scan_finish(scan_state); psql_scan_reset(scan_state); count_eof = 0; slashCmdStatus = CMD_UNKNOWN; prompt_status = PROMPT_READY; + if (pset.cur_cmd_interactive) + pgclear_history(history_buf); if (pset.cur_cmd_interactive) putc('\n', stdout); *************** *** 138,143 **** --- 147,161 ---- psql_scan_reset(scan_state); slashCmdStatus = 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); + } + } /* *************** *** 212,218 **** */ psql_scan_setup(scan_state, line, strlen(line)); success = true; ! while (success || !die_on_error) { PsqlScanResult scan_result; --- 230,242 ---- */ 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; *************** *** 229,234 **** --- 253,259 ---- (scan_result == PSCAN_EOL && GetVariableBool(pset.vars, "SINGLELINE"))) { + /* execute query */ success = SendQuery(query_buf->data); slashCmdStatus = success ? CMD_SEND : CMD_ERROR; *************** *** 249,258 **** --- 274,286 ---- * newline again. This avoids any change to query_buf when a * line contains only a backslash command. */ + + if (query_buf->len == added_nl_pos) query_buf->data[--query_buf->len] = '\0'; added_nl_pos = -1; + slashCmdStatus = HandleSlashCmds(scan_state, query_buf->len > 0 ? query_buf : previous_buf); *************** *** 266,271 **** --- 294,300 ---- appendPQExpBufferStr(query_buf, previous_buf->data); } + if (slashCmdStatus == CMD_SEND) { success = SendQuery(query_buf->data); *************** *** 287,292 **** --- 316,329 ---- 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,338 **** --- 370,376 ---- destroyPQExpBuffer(query_buf); destroyPQExpBuffer(previous_buf); + destroyPQExpBuffer(history_buf); psql_scan_destroy(scan_state); Index: prompt.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/prompt.c,v retrieving revision 1.40 diff -c -r1.40 prompt.c *** prompt.c 15 Oct 2005 02:49:40 -0000 1.40 --- prompt.c 8 Dec 2005 04:04:18 -0000 *************** *** 12,17 **** --- 12,18 ---- #include "settings.h" #include "common.h" + #include "pqexpbuffer.h" #include "input.h" #include "variables.h" Index: tab-complete.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v retrieving revision 1.141 diff -c -r1.141 tab-complete.c *** tab-complete.c 18 Nov 2005 16:31:11 -0000 1.141 --- tab-complete.c 8 Dec 2005 04:04:23 -0000 *************** *** 43,48 **** --- 43,49 ---- #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,56 **** #include <ctype.h> #include "libpq-fe.h" - #include "pqexpbuffer.h" #include "common.h" #include "settings.h" --- 51,56 ----
---------------------------(end of broadcast)--------------------------- TIP 1: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly