From 5553c084c815aa70b8bef139bac0694740f1dc0e Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Wed, 28 Nov 2018 09:36:59 +0900
Subject: [PATCH 2/3] With-context version of tab-completion debug print.

This is another version of tab-completion debug print. This shows
input context instead of just the current word.
---
 src/bin/psql/tab-complete.c | 53 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 12 deletions(-)

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 747587030b..704a6879a8 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -73,24 +73,46 @@ extern char *filename_completion_function();
 #endif
 
 #undef completion_matches
-#define completion_matches(t, f) completion_debug(__LINE__, (t), (f))
+#define completion_matches(text, func) \
+	completion_debug(__LINE__, (text), (func), \
+					 previous_words, previous_words_count)
 
-static char **completion_debug(int line,
-							   const char *text, rl_compentry_func_t *func)
+#define DEBUG_NCONTEXT 3
+
+static char **
+completion_debug(int line, const char *text, rl_compentry_func_t *func,
+				 char **previous_words, int previous_words_count)
 {
 	char **list = org_completion_matches(text, func);
+	int nwords = DEBUG_NCONTEXT;
 
-	if (pset.logfile)
+	if (pset.debug && pset.logfile)
 	{
 		/* Emit completion log */
 
 		/* Enclose empty list with brackets since it is an intermediate state
 		 * which is immediately followed by a non-empty list.
 		 */
-		fprintf(pset.logfile, "%s:%d:%s\"%s\" -> (", __FILE__, line, list ? "" : "[", text);
+		fprintf(pset.logfile, "%s:%d: %s(", __FILE__, line, list ? "" : "[");
+
+		/* input context */
+		if (previous_words_count > 0)
+		{
+			if (previous_words_count > nwords)
+				fprintf(pset.logfile, "...");
+			else
+				nwords = previous_words_count;
+			for (int i = 0 ; i < nwords ; ++i)
+				fprintf(pset.logfile, "%s ", previous_words[nwords - i - 1]);
+		}
+
+		fprintf(pset.logfile, "[%s]) -> (", text);
+
+		/* completion result */
 		for (int i = 0; list && list[i]; ++i)
 			fprintf(pset.logfile, "%s\"%s\"", i ? ", " : "", list[i]);			
 		fprintf(pset.logfile, ")%s\n", list ? "": "]");
+
 		fflush(pset.logfile);
 	}
 
@@ -1050,7 +1072,8 @@ static void append_variable_names(char ***varnames, int *nvars,
 					  int *maxvars, const char *varname,
 					  const char *prefix, const char *suffix);
 static char **complete_from_variables(const char *text,
-						const char *prefix, const char *suffix, bool need_value);
+					  const char *prefix, const char *suffix, bool need_value,
+					  char ** previous_words, int previous_words_count);
 static char *complete_from_files(const char *text, int state);
 
 static char *pg_strdup_keyword_case(const char *s, const char *ref);
@@ -1423,11 +1446,14 @@ psql_completion(const char *text, int start, int end)
 	else if (text[0] == ':' && text[1] != ':')
 	{
 		if (text[1] == '\'')
-			matches = complete_from_variables(text, ":'", "'", true);
+			matches = complete_from_variables(text, ":'", "'", true,
+ 						previous_words, previous_words_count);
 		else if (text[1] == '"')
-			matches = complete_from_variables(text, ":\"", "\"", true);
+			matches = complete_from_variables(text, ":\"", "\"", true,
+ 						previous_words, previous_words_count);
 		else
-			matches = complete_from_variables(text, ":", "", true);
+			matches = complete_from_variables(text, ":", "", true,
+ 						previous_words, previous_words_count);
 	}
 
 	/* If no previous word, suggest one of the basic sql commands */
@@ -3588,9 +3614,11 @@ psql_completion(const char *text, int start, int end)
 			COMPLETE_WITH_CS("single", "double");
 	}
 	else if (TailMatchesCS("\\unset"))
-		matches = complete_from_variables(text, "", "", true);
+		matches = complete_from_variables(text, "", "", true,
+ 						previous_words, previous_words_count);
 	else if (TailMatchesCS("\\set"))
-		matches = complete_from_variables(text, "", "", false);
+		matches = complete_from_variables(text, "", "", false,
+ 						previous_words, previous_words_count);
 	else if (TailMatchesCS("\\set", MatchAny))
 	{
 		if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
@@ -4142,7 +4170,8 @@ append_variable_names(char ***varnames, int *nvars,
  */
 static char **
 complete_from_variables(const char *text, const char *prefix, const char *suffix,
-						bool need_value)
+						bool need_value,
+						char ** previous_words, int previous_words_count)
 {
 	char	  **matches;
 	char	  **varnames;
-- 
2.16.3

