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

Reply via email to