repl: suggest quoted attribute names when necessary #450

Open
opened 2024-07-15 04:55:56 +00:00 by ian-h-chamberlain · 2 comments

Tab-completed attribute suggestions in nix repl don't work very well when they contain characters that need to be quoted (e.g. ., @), for example:

Lix 2.90.0
Type :? for help.
nix-repl> x = { foo.bar.baz = {}; "hello@example.com" = {}; }

nix-repl> x.
x.foo                x.hello@example.com
nix-repl> x.hello@example.com
error: syntax error, unexpected '@', expecting end of file
       at «string»:1:8:
            1| x.hello@example.com
             |        ^

Describe the solution you'd like

Suggest e.g. "hello@example.com" instead of hello@example.com for cases like this that need to be quoted to resolve an attribute name, so that the suggestion is actually valid.

Describe alternatives you've considered

Don't suggest attribute names like this at all? Seems like that would be a poor UX. No other alternatives come to mind at the moment.

Additional context

I looked into implementing this myself, and I'd like to send a patch if I can figure it out! Actually getting the quoted attribute name is pretty straightforward, but hooking the quoted completion up to editline seems a little harder. It appears that " is treated as a special character denoting a new word, so once the user types a single " the completion callback no longer sees the left-hand-side of the . to evaluate. It looks like the readline equivalents for rl_completer_quote_characters or similar are unimplemented in editline.

From digging a bit more, in v1.16 they added some APIs which appear to be fed the entire input line, instead of just the "current word" I guess? From a little bit of experimentation it seems possible to use these to workaround the limitation above, and fall back to the current implementation in the normal case.

There's one oddity, which is that rl_completion_entry_function is not declared in their public header, but it is documented in the changelog and is an existing readline API, so it's probably fine/forward-compatible to declare it manually (and perhaps send a patch upstream to add the declaration).

TL;DR

  • editline doesn't handle quotes well for this case
  • There are some (barely-documented) APIs that may be usable to implement this
  • Doing so will require an extern since editline.h doesn't declare it

Do those caveats seem okay / should I take a stab at implementing this? It seems like a freeze-friendly kind of feature but I thought I'd start some discussion before putting too much time into it.

## Is your feature request related to a problem? Please describe. Tab-completed attribute suggestions in `nix repl` don't work very well when they contain characters that need to be quoted (e.g. `.`, `@`), for example: ``` Lix 2.90.0 Type :? for help. nix-repl> x = { foo.bar.baz = {}; "hello@example.com" = {}; } nix-repl> x. x.foo x.hello@example.com nix-repl> x.hello@example.com error: syntax error, unexpected '@', expecting end of file at «string»:1:8: 1| x.hello@example.com | ^ ``` ## Describe the solution you'd like Suggest e.g. `"hello@example.com"` instead of `hello@example.com` for cases like this that need to be quoted to resolve an attribute name, so that the suggestion is actually valid. ## Describe alternatives you've considered Don't suggest attribute names like this at all? Seems like that would be a poor UX. No other alternatives come to mind at the moment. ## Additional context I looked into implementing this myself, and I'd like to send a patch if I can figure it out! Actually getting the quoted attribute name is pretty straightforward, but hooking the quoted completion up to `editline` seems a little harder. It appears that `"` is treated as a special character denoting a new word, so once the user types a single `"` the completion callback no longer sees the left-hand-side of the `.` to evaluate. It looks like the `readline` equivalents for `rl_completer_quote_characters` or similar are unimplemented in `editline`. From digging a bit more, in [v1.16](https://github.com/troglobit/editline/blob/master/ChangeLog.md#1160---2018-09-16) they added some APIs which appear to be fed the _entire_ input line, instead of just the "current word" I guess? From a little bit of experimentation it seems possible to use these to workaround the limitation above, and fall back to the current implementation in the normal case. There's one oddity, which is that `rl_completion_entry_function` is not declared in their public header, but it is documented in the changelog and is an existing `readline` API, so it's probably fine/forward-compatible to declare it manually (and perhaps send a patch upstream to add the declaration). TL;DR - `editline` doesn't handle quotes well for this case - There are some (barely-documented) APIs that may be usable to implement this - Doing so will require an `extern` since `editline.h` doesn't declare it Do those caveats seem okay / should I take a stab at implementing this? It seems like a [freeze-friendly](https://wiki.lix.systems/books/lix-contributors/page/freezes-and-recommended-contributions) kind of feature but I thought I'd start some discussion before putting too much time into it.
Owner

this is not the only issue with editline, fwiw. there have been ideas of switching lix to a different line editing framework that doesn't have these shortcomings (replxx was a contender), but so far no decision has been made on that.

Do those caveats seem okay / should I take a stab at implementing this?

sure! rl_attempted_completion_function is externd at least, and that seems to be the most important one for us.

It seems like a freeze-friendly kind of feature but I thought I'd start some discussion before putting too much time into it.

lix is not currently frozen, the wiki was just a bit out of date. :)

this is not the only issue with editline, fwiw. there have been ideas of switching lix to a different line editing framework that doesn't have these shortcomings ([replxx](https://github.com/AmokHuginnsson/replxx) was a contender), but so far no decision has been made on that. > Do those caveats seem okay / should I take a stab at implementing this? sure! `rl_attempted_completion_function` is externd at least, and that seems to be the most important one for us. > It seems like a freeze-friendly kind of feature but I thought I'd start some discussion before putting too much time into it. lix is not currently frozen, the wiki was just a bit out of date. :)
jade added the
ux
Area/repl
labels 2024-08-07 06:02:44 +00:00
Member

This issue was mentioned on Gerrit on the following CLs:

  • commit message in cl/1783 ("repl: tab-complete quoted attribute names")
<!-- GERRIT_LINKBOT: {"cls": [{"backlink": "https://gerrit.lix.systems/c/lix/+/1783", "number": 1783, "kind": "commit message"}], "cl_meta": {"1783": {"change_title": "repl: tab-complete quoted attribute names"}}} --> This issue was mentioned on Gerrit on the following CLs: * commit message in [cl/1783](https://gerrit.lix.systems/c/lix/+/1783) ("repl: tab-complete quoted attribute names")
Sign in to join this conversation.
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#450
No description provided.