Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-FLAG:"PATH" Style Completion Not Working #59

Closed
CampinCarl opened this issue Jan 22, 2021 · 8 comments
Closed

-FLAG:"PATH" Style Completion Not Working #59

CampinCarl opened this issue Jan 22, 2021 · 8 comments
Labels
bug Something isn't working

Comments

@CampinCarl
Copy link

First, huge thanks to the developers for keeping this project alive; it's awesome!

I'm trying to get -flag:"path" style completion working, which works in v0.4.9 when a double quote is present. Here's a use case example with Saxonica's XSLT utility, ref: Saxon Documentation - Running XSLT from the Command Line

C:\>Transform.exe -xsl:"foo.xsl" -s:"source.xml"
  1. Command completion works fine, i.e., transf + [TAB] = Transform.exe
  2. Flag completion works (via Lua), i.e., -xs + [TAB] = -xsl:
  3. Path completion does not work, i.e., -xsl:" or -xsl:"foo + [TAB] = -xsl:"/-xsl:"foo (no path completion)

I think it might be possible to replicate this behavior in Lua? Conceptually, I'm looking for a way to treat the colon as a separator between the -xsl flag and the foo.xsl argument, similar to the Linking Parsers example. The clink.filematches function looks suitable for this purpose, but I don't know how to solve the colon issue.

Any advice from the devs/community would be greatly appreciated.

@chrisant996
Copy link
Owner

Makes sense, thanks for the description and context information.

I'll take a look. Yes, a generator can handle that manually (see getwordbreakinfo, or something like that; I forget the exact name offhand). But this behavior should be built in so that argmatchers get it for free. Plus, it presents an interesting edge case for input colorization.

@CampinCarl
Copy link
Author

CampinCarl commented Jan 22, 2021

You're welcome and thanks for taking a look at this. I'll play around with :getwordbreakinfo(), though admittedly I'm not an expert with Lua (should be fun though!).

@chrisant996 chrisant996 added the bug Something isn't working label Jan 23, 2021
@chrisant996
Copy link
Owner

chrisant996 commented Jan 23, 2021

This is a very good find, thank you!

complete indeed doesn't work at all in that case. However, menu-complete is sort of able to insert matches, but can't handle more than one path component (e.g. -x:"foo but not -s:"foo\bar).

The problem is a nuanced mismatch between how Readline and Clink (v1.0 and higher) think about match expansion. Clink breaks the line into words, and uses completion to extend words. Readline backtracks from the current cursor point to find a point to start matching; one point is an unclosed quote, another is a word break, and so on.

Readline sees foo -x:" as starting a match completion after the unclosed ".
Clink sees foo -x:" as two words foo and -x:", and tries to complete the word -x:".

The Clink rewrite wasn't designed to handle this case, so I'll need to do some minor surgery on the design.

Clink needs to be able to see it as three words foo, -x:, and ". That's important for completion, for linked argmatchers so subsequent words are interpreted correctly, and for input colorization so -x: gets colored as a flag even though there isn't a space after it.

But there's more to it:

  • If there's a linked argmatcher for a flag ending in : or =, then the next part should be considered a separate word so the argmatcher can supply matches for it.
  • If there's not a linked argmatcher, then the next part should not be considered a separate word. Except that input colorization should consider it a separate word. Tricksy...

This will require some thought to make sure it's all handled well, without making things complicated for lua scripts.

@chrisant996
Copy link
Owner

Clink 0.4.9 does not work correctly in this case, by the way. It interprets the quoted string as a separate word as though it were not connected to the -flag: string.

For example:

  • net -flag:"Tab lists arg1 matches as possible completions: accounts, computer, config, etc.
  • net -flag:"config" Tab lists arg2 matches for config as possible completions: server, workstation.
  • git -flag:"checkout" Tab lists files plus branch names as though git checkout had been used.

@chrisant996
Copy link
Owner

Here's what I think is needed:

  1. Make the -flag:"text" case not be handled by argmatchers, and simply default to file completions.
  2. Make the -flag: part be colored as a Flag, and make the "text" part be colored as Other.
  3. Explore adding some lua syntax to supply a match generator for a flag with no space after it. Maybe the + operator could be taken over, e.g. { "-flag:" + some_function_name }.
  4. Provide some way for a custom classifier to apply a classification to any region in the input line, not just to a pre-parsed word.
  5. Provide some way for a custom classifier to apply any arbitrary color to a pre-parsed word or to any region in the input line.

I've opened 3 new issues to track those:
#61 tracks points 1 and 3.
#62 tracks point 2.
#63 tracks points 4 and 5.

Thanks again @CampinCarl for noticing and reporting this!

FWIW, point 3 is "nice to have", but is not required -- I think it shouldn't be very expensive to support, but I can't promise anything just yet. The reason it isn't strictly required is that custom generators can be written to handle any arbitrarily complex syntax in an input line. For example, a custom generator handles environment variable completions embedded within words, and the entire argmatcher system is itself just a built-in custom generator.

chrisant996 added a commit that referenced this issue Jan 25, 2021
Readline chooses word break positions differently than Clink does.
Readline just scans backwards looking for certain characters.  That
leads to `"ab cd"#` completing to `"ab cd"ab cd" #`, and issue #59 where
`-flag:"#` completes wrongly.

Clink parses the line into words, and lets lua scripts influence word
break positions.  So Clink must always force Readline to use Clink's word
break position, otherwise the two systems can essentially try to
complete different words.  Which of course goes poorly.
@CampinCarl
Copy link
Author

Thanks Chris! Interesting point on v0.4.9. Sounds like it "worked" for what I needed but wasn't actually working as intended. I'll keep an eye on the new issues you've opened.

@CampinCarl
Copy link
Author

Checking in to say the new build works great for this use case. Thanks!

@chrisant996
Copy link
Owner

Thanks for confirming!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants