David Fetter <da...@fetter.org> writes: > On Mon, Sep 20, 2021 at 08:26:51PM +0100, Dagfinn Ilmari Mannsåker wrote: > >> The same applies to any completion after a MatchAny that ends in a any >> of the WORD_BREAKS characters (except whitespace and () which are >> handled specially). >> >> #define WORD_BREAKS "\t\n@$><=;|&{() " >> >> IMO a fix should be more principled than just special-casing semicolon >> and CREATE TABLE. Maybe get_previous_words() should stop when it sees >> an unquoted semicolon? > > Is there some reason get_previous_words() shouldn't stop for > everything that's WORD_BREAKS? If not, making that the test might make the > general rule a little simpler to write, and if WORD_BREAKS ever > changed, for example to include all space, or all breaking space, or > similar, the consequences would at least not propagate through > seemingly unrelated code.
By "stopping" I meant ignoring everything before the last semicolon when splitting the buffer into words, i.e. not putting them into the previous_words array, so they're not considered by the (Tail|Head)?Matches(CS)? macros. WORD_BREAKS is the list of characters used for splitting the input buffer into the previous_words array, so it would need to keep going past those, or you'd only be able to match the last word when tab completing, rendering the entire exercise pointless. > At the moment, get_previous_words() does look for everything in > WORD_BREAKS, and then accounts for double quotes (") and then does > something clever to account for double quotes and the quoting behavior > that doubling them ("") accomplishes. Anyhow, that looks like it > should work in this case, but clearly it's not. WORD_BREAK characters inside double-quoted identifiers are handled correclty, but only after you've typed the closing quote. If you have an ambiguous prefix that contains a WORD_BREAK character, you can't tab-complete the rest: ilmari@[local]:5432 ~=# drop table "foo<tab><tab> "foo$bar" "foo$zot" "foo-bar" "foo-zot" ilmari@[local]:5432 ~=# drop table "foo-<tab><tab> "foo-bar" "foo-zot" ilmari@[local]:5432 ~=# rop table "foo$<tab><tab> ilmari@[local]:5432 ~=# drop table "foo$bar" <tab><tab> cascade restrict Tangentially, I would argue that $ shouldn't be a WORD_BREAK character, since it's valid in unquoted identifiers (except at the start, just like numbers). But you do need to quote such identifiers when tab-completing, since quote_ident() quotes anything tht's not all lowercase letters, underscores and numbers. - ilmari