From 886f71294ba4ec6618b1707858a9eacef4d188ef Mon Sep 17 00:00:00 2001 From: Yugo Nagata Date: Thu, 5 Jun 2025 09:39:09 +0900 Subject: [PATCH v5 3/3] Improve tab completion for COPY option lists Previously, only the first option in a parenthesized list was suggested during tab completion. Subsequent options after a comma were not completed. This commit enhances the behavior to suggest valid options after each comma. --- src/bin/psql/tab-complete.in.c | 53 +++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index c565c0218e1..079ee1630e5 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -3353,30 +3353,35 @@ match_previous_words(int pattern_id, Matches("COPY|\\copy", MatchAny, "FROM", "PROGRAM", MatchAny)) COMPLETE_WITH("WITH (", "WHERE"); - /* Complete COPY FROM [PROGRAM] filename WITH ( */ - else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAnyExcept("PROGRAM"), "WITH", "(") || - Matches("COPY|\\copy", MatchAny, "FROM", "PROGRAM", MatchAny, "WITH", "(")) - COMPLETE_WITH(Copy_from_options); - - /* Complete COPY TO [PROGRAM] filename WITH ( */ - else if (Matches("COPY|\\copy", MatchAny, "TO", MatchAnyExcept("PROGRAM"), "WITH", "(") || - Matches("COPY|\\copy", MatchAny, "TO", "PROGRAM", MatchAny, "WITH", "(")) - COMPLETE_WITH(Copy_to_options); - - /* Complete COPY FROM|TO [PROGRAM] WITH (FORMAT */ - else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAnyExcept("PROGRAM"), "WITH", "(", "FORMAT") || - Matches("COPY|\\copy", MatchAny, "FROM|TO", "PROGRAM", MatchAny, "WITH", "(", "FORMAT")) - COMPLETE_WITH("binary", "csv", "text"); - - /* Complete COPY FROM [PROGRAM] filename WITH (ON_ERROR */ - else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAnyExcept("PROGRAM"), "WITH", "(", "ON_ERROR") || - Matches("COPY|\\copy", MatchAny, "FROM", "PROGRAM", MatchAny, "WITH", "(", "ON_ERROR")) - COMPLETE_WITH("stop", "ignore"); - - /* Complete COPY FROM [PROGRAM] filename WITH (LOG_VERBOSITY */ - else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAnyExcept("PROGRAM"), "WITH", "(", "LOG_VERBOSITY") || - Matches("COPY|\\copy", MatchAny, "FROM", "PROGRAM", MatchAny, "WITH", "(", "LOG_VERBOSITY")) - COMPLETE_WITH("silent", "default", "verbose"); + /* Complete COPY FROM|TO [PROGRAM] filename WITH ( */ + else if (HeadMatches("COPY|\\copy", MatchAny, "FROM|TO", MatchAnyExcept("PROGRAM"), "WITH", "(") || + HeadMatches("COPY|\\copy", MatchAny, "FROM|TO", "PROGRAM", MatchAny, "WITH", "(")) + { + if (!HeadMatches("COPY|\\copy", MatchAny, "FROM|TO", MatchAnyExcept("PROGRAM"), "WITH", "(*)") && + !HeadMatches("COPY|\\copy", MatchAny, "FROM|TO", "PROGRAM", MatchAny, "WITH", "(*)")) + { + /* We're in an unfinished parenthesized option list. */ + if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) + { + if (HeadMatches("COPY|\\copy", MatchAny, "FROM")) + COMPLETE_WITH(Copy_from_options); + else + COMPLETE_WITH(Copy_to_options); + } + + /* Complete COPY FROM|TO filename WITH (FORMAT */ + else if (TailMatches("FORMAT")) + COMPLETE_WITH("binary", "csv", "text"); + + /* Complete COPY FROM filename WITH (ON_ERROR */ + else if (TailMatches("ON_ERROR")) + COMPLETE_WITH("stop", "ignore"); + + /* Complete COPY FROM filename WITH (LOG_VERBOSITY */ + else if (TailMatches("LOG_VERBOSITY")) + COMPLETE_WITH("silent", "default", "verbose"); + } + } /* Complete COPY FROM [PROGRAM] WITH () */ else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAnyExcept("PROGRAM"), "WITH", MatchAny) || -- 2.43.0