commit 045c92b10eb8777d29fc920c55561d645c0b8f30
Author: Andreas Karlsson <andreas@proxel.se>
Date:   Fri Feb 3 13:05:48 2017 +0100

    Add compleition for \help DROP|ALTER

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index d6fffcf42f..653630dac2 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1262,6 +1262,17 @@ psql_completion(const char *text, int start, int end)
 	(previous_words_count >= 2 && \
 	 word_matches_cs(p1, prev_wd) && \
 	 word_matches_cs(p2, prev2_wd))
+#define TailMatchesCS3(p3, p2, p1) \
+	(previous_words_count >= 3 && \
+	 word_matches_cs(p1, prev_wd) && \
+	 word_matches_cs(p2, prev2_wd) && \
+	 word_matches_cs(p3, prev3_wd))
+#define TailMatchesCS4(p4, p3, p2, p1) \
+	(previous_words_count >= 4 && \
+	 word_matches_cs(p1, prev_wd) && \
+	 word_matches_cs(p2, prev2_wd) && \
+	 word_matches_cs(p3, prev3_wd) && \
+	 word_matches_cs(p4, prev4_wd))
 
 	/*
 	 * Macros for matching N words beginning at the start of the line,
@@ -3256,8 +3267,51 @@ psql_completion(const char *text, int start, int end)
 
 	else if (TailMatchesCS1("\\encoding"))
 		COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
-	else if (TailMatchesCS1("\\h") || TailMatchesCS1("\\help"))
+	else if (TailMatchesCS1("\\h|\\help"))
 		COMPLETE_WITH_LIST(sql_commands);
+	else if (TailMatchesCS2("\\h|\\help", MatchAny))
+	{
+		if (TailMatches1("DROP"))
+			matches = completion_matches(text, drop_command_generator);
+		else if (TailMatches1("ALTER"))
+		{
+			static const char *const list_ALTER[] =
+			{"AGGREGATE", "COLLATION", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN",
+				"EVENT TRIGGER", "EXTENSION", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "FUNCTION",
+				"GROUP", "INDEX", "LANGUAGE", "LARGE OBJECT", "MATERIALIZED VIEW", "OPERATOR",
+				"POLICY", "PUBLICATION", "ROLE", "RULE", "SCHEMA", "SERVER", "SEQUENCE",
+				"SUBSCRIPTION", "SYSTEM", "TABLE", "TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE",
+			"USER", "USER MAPPING FOR", "VIEW", NULL};
+
+			COMPLETE_WITH_LIST(list_ALTER);
+		}
+	}
+	else if (TailMatchesCS3("\\h|\\help", MatchAny, MatchAny))
+	{
+		if (TailMatches2("DROP", "ACCESS"))
+			COMPLETE_WITH_CONST("METHOD");
+		else if (TailMatches2("ALTER", "DEFAULT"))
+			COMPLETE_WITH_CONST("PRIVILEGES");
+		else if (TailMatches2("ALTER|DROP", "EVENT"))
+			COMPLETE_WITH_CONST("TRIGGER");
+		else if (TailMatches2("ALTER|DROP", "FOREIGN"))
+			COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
+		else if (TailMatches2("ALTER", "LARGE"))
+			COMPLETE_WITH_CONST("OBJECT");
+		else if (TailMatches2("ALTER|DROP", "MATERIALIZED"))
+			COMPLETE_WITH_CONST("VIEW");
+		else if (TailMatches2("ALTER|DROP", "TEXT"))
+			COMPLETE_WITH_CONST("SEARCH");
+		else if (TailMatches2("ALTER|DROP", "USER"))
+			COMPLETE_WITH_CONST("MAPPING FOR");
+	}
+	else if (TailMatchesCS4("\\h|\\help", MatchAny, MatchAny, MatchAny))
+	{
+		if (TailMatches3("ALTER|DROP", "FOREIGN", "DATA"))
+			COMPLETE_WITH_CONST("WRAPPER");
+		else if (TailMatches3("ALTER|DROP", "USER", "MAPPING"))
+			COMPLETE_WITH_CONST("FOR");
+	}
 	else if (TailMatchesCS1("\\l*") && !TailMatchesCS1("\\lo*"))
 		COMPLETE_WITH_QUERY(Query_for_list_of_databases);
 	else if (TailMatchesCS1("\\password"))
