From: Kyotaro Horiguchi Date: Wed, 26 Oct 2016 12:06:33 +0900 Subject: [PATCH 6/6] Add README for tab-completion. --- src/bin/psql/README.completion | 165 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 src/bin/psql/README.completion diff --git a/src/bin/psql/README.completion b/src/bin/psql/README.completion new file mode 100644 index 0000000..65981e4 --- /dev/null +++ b/src/bin/psql/README.completion @@ -0,0 +1,165 @@ +Word completion of interactive psql +=================================== + +psql supports word completion on interactive input. The core function +of the feature is psql_completion_internal in tab-complete.c. A bunch +of macros are provided in order to make it easier to read and maintain +the completion code. psql_completion is called with reference console +input stored in char ** previous_words in reverse order but developers +don't need to be aware of the detail. Most of the operations can be +described using the provided macros. + +Basic structure of the completion code +-------------------------------------- + +The main part of the function is just a series of completion +definitions, where the first match wins. Each definition basically is +in the following shape. + + if (*matching expression*) + *enumeration of words for completion, then return* + +The matching expression is examined against previous_words which +contains the whole command line before the last space. The completion +code enumerates the expected words. For example, for "CREATE " +the word list to be matched is ["CREATE"] and the prefix for +completion is nothing. For "CREATE INDEX i", the list is ["CREATE", +"INDEX"] and the prefix for enumeration is "i". + + +Matching expression macros +-------------------------- +There are four types of matching expression macros. + +- MatchesN(word1, word2 .. , wordN) + + true iff the word list is exactly the same as the paremeter. + +- HeadMatchesN(word1, word2 .., wordN) + + true iff the first N words in the word list matches the parameter. + +- TailMatchesN(word1, word2 .., wordN) + + true iff the last N words in the word list matches the parameter. + +- MidMatchesN(pos, word1, word2 .., wordN) + + true iff N successive words starts from pos in the word list matches + the parameter. The position is 1-based. + +Special matching words +---------------------- + +A defined symbol MatchAny matches any word. If you want to match any +of several words, multiple words concatenated by '|' can be +used. "CREATE|UPDATE" matches any of "CREATE" and "UPDATE". + + +Enumeration macros +----------------- +There are N types of word enumeration macros. + +- COMPLETE_WITH_QUERY(query), COMPLETE_WITH_QUERY_KW(query, addon) + + Suggest completion words acquired using the given query. The details + of the query is seen in the comment for _complete_from_query(). Word + matching is case-sensitive. + + The latter form takes an additional parameter, which should be a + fragment of query starts with " UNION " followed by a query string + which gives some additional words. For case-insensitive suggestion, + this could be as simple as a static query string but for + case-sensitive case, where the letter case of suggested words + follows input, ADDLISTN() macro can be used. + +- COMPLETE_WITH_SCHEMA_QUERY(squery), + COMPLETE_WITH_SCHEMA_QUERY_KW(squery, addon) + + Suggest words based on a "schema query", which is a struct that + containing parameters. You will see the details in the comment for + _complete_from_query(). Word maching is case-sensitive. + + Just same as COMPLETE_WITH_QUERY_KW, the latter form takes a + fragment query same to that for COMPLETE_WITH_QUERY_KW. + +- COMPLETE_WITH_LIST_CS(list) + + Suggest completion words given as a string array. Word matching is + case-sensitive. + +- COMPLETE_WITH_LIST_CSN(s1, s2.. ,sN) + + Shortcut for COMPLETE_WITH_LIST_CS. + +- COMPLETE_WITH_LIST(list) + + Same as COMPLETE_WITH_LIST_CS except that word matching is + case-insensitive and the letter case of suggested words is + determined according to COMP_KEYWORD_CASE. + +- COMPLETE_WITH_LISTN(s1, s2.. ,sN) + + Shortcut for COMPLETE_WITH_LIST. + +- COMPLETE_WITH_CONST(string) + + Same as COMPLETE_WITH_LIST but with just one suggestion. + +- COMPLETE_WITH_ATTR(relation, addon) + + Suggest attribute names for the given relation. Word matching is + case-sensitve. + +- COMPLETE_WITH_FUNCTION_ARG(function) + + Suggest function name for the given SQL function. Word matching is + case-sensitve. + +- COMPLETE_THING(relpos) + + Suggest any object name designated by the word at relpos from the + current word. COMPLETE_THING(-1) for "... TABLE " enumerates names + of all available tables. + + +Additional keywords for COMPLETE_WITH(_SCHEMA)_QUERY +---------------------------------------------------- + +Some syntaxes need suggestion by mixture of object names and +keywords. Object names are enumarated with +COMPLETE_WITH(_SCHEMA)_QUERY but keywords should be added manually +onto them. COMPLETE_WITH(_SCHEMA)_QUERY_KW takes a fragment query that +gives keywords to be suggested with the object names. Since the +framgent queriy is just appended to the main query so it is in the +form of ' UNION ' that adds arbitrary number of tuples +contain a text value. For example, + +" UNION ALL SELECT 'CURRENT_USER' UNION ALL SELECT 'PUBLIC'" + +If you want the case of the keywords to follow input, ADDLISTN() macro +provides a fragment query containing such keywords. + +ADDLIST3("CURRENT_USER", "PUBLIC", "USER") for input 'c' returns a +fragment query equivalent to the following, + +" UNION ALL SELECT 'current_user' UNION ALL SELECT 'public'" + + +Removing "NOISE" words +---------------------------------------------------- + +Many syntaxes has "NOISE" words, that is, words that has no effect on +the following completion. For example, the existence of the second +word in "CREATE UNIQUE INDEX" makes no difference for further +completion behavior. Removing such words makes further completion code +simpler. + +COLLAPSE(s, l) removes l words starts from s from previous_words. + +if (Matches("CREATE", "UNIQUE", "INDEX")) + COLLAPSE(2, 1); + +After the above code, the previous_words is ["CREATE", "INDEX"] so the +following completion definitions need not care about the removed words. + -- 2.9.2 ----Next_Part(Mon_Oct_31_10_15_48_2016_300)-- Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ----Next_Part(Mon_Oct_31_10_15_48_2016_300)----