Thanks to visit codestin.com
Credit goes to github.com

Skip to content

FZF on argument types - #4519

Merged
aryairani merged 27 commits into
trunkfrom
cp/fzf-args
Jan 4, 2024
Merged

aryairani merged 27 commits into
trunkfrom
cp/fzf-args

Conversation

@ChrisPenner

@ChrisPenner ChrisPenner commented Dec 15, 2023

Copy link
Copy Markdown
Member

Overview

Adds FZF argument resolution to most commands that could support it.

The FZF resolver kicks in when:

  • A required argument hasn't been specified (but has a resolver configured)
  • An argument is filled with the ! placeholder. We can bikeshed this, but it's invalid to call a definition just ! so it seemed a reasonable choice.

When triggered, the fuzzy-finder will load all the possible options and let you select one (or more) depending on the argument type, e.g. a OnePlus argument lets you multi-select whereas an Optional argument just lets you select zero or one arg.

E.g.

image

UCM will also now re-print the command that you ran with all arguments from numerical and fzf expansion expanded so you can see what was actually executed, e.g.

scrap/new> find

  1. derp : [(Nat, [Char])]
  2. meow : [(Char, Nat)]


scrap/new> view 1-2
scrap/new> view derp#poh6oktqjr0vi7sa10ccrbtn1qnda25tphren16j8mc1nkqpmqm2edqe7vgj3e2kbfki42411rq9stp7j21odrs8n6rgdokl8ra7of0 meow#p1sob5bkpnbeudcn40r923b0bkp2u1gp8182g7u1nf5n0rfj21pd6krotl5an2k06rrir453s38j43d06kj334afm30dqkbjklet7h8

  derp : [(Nat, [Char])]
  derp = [(1, [?A, ?E, ?I, ?O, ?U])]

  meow : [(Char, Nat)]
  meow =
    derp
      |> (base.data.List.flatMap cases
           (num, chars) ->
             chars
               |> (base.data.List.map cases
                    char -> (Char.toLowercase char, num)))

Kapture 2023-12-19 at 13 22 05

Implementation notes

  • Wires in an fzfResolver onto the ArgumentType.
  • Adds a step AFTER numbered-arg expansion but BEFORE argument parsing where FZF can fill in any missing or ! arguments.
  • Arguments provided by FZF are just plain-text, so they'll still be parsed by the command parser as usual. It's up the the argument-type to only provide valid options.
  • Multiple options resolvers can easily be combined.
  • Now we pass the Codebase into the parseInput command so I can fetch projects, seems uncontroversial.
  • Adds debug.fuzzy-options which allows listing fuzzy completion options in transcripts.

Interesting/controversial decisions

  • This is a really nice UX for people who know what's happening, but how can we make sure we sign-post this to new users so they know it exists and understand it?
  • Printing the expanded args can be pretty ugly when they're all hash-qualified 😬

Test coverage

  • debug.fuzzy-options transcripts

Loose ends

  • If FZF is 'ctrl-c'd we shouldn't continue to running the command
  • The selected arguments are never actually printed in the terminal, so it's tough to tell what you did when you look back.
  • Do we put the fully resolved command into the haskeline history, or just the command that triggered it? (Same question for numerical args I guess)
    • Discussed this in slack, we ideally want all the arguments expanded out in the CLI history, but should wait until we have an edit.namespace to make this change so we don't break the edit 1-1000 workflow.
  • We should eventually figure out how to stream things to fzf to speed it up a bit, but TBH we should just be caching the names for the current branch so that EVERYTHING gets a speed up

@ChrisPenner
ChrisPenner marked this pull request as ready for review December 19, 2023 19:17
@ChrisPenner ChrisPenner self-assigned this Dec 19, 2023
@ceedubs

ceedubs commented Dec 19, 2023

Copy link
Copy Markdown
Contributor

Ooh the ! syntax also solves a papercut that I occasionally run into but didn't have a proposal for:

Sometimes I want to do an ls to see what is in the Map namespace. If I do a no-arg ls it does an ls on the current namespace, which is understandable. But I also don't want to have to type out ls lib.base_2_9_1.data.Map. Now I can do ls !, type Map, and hit enter!

This PR gets a ❤️ from me.

@aryairani

aryairani commented Dec 19, 2023

Copy link
Copy Markdown
Contributor

should wait until we have an edit.namespace to make this change so we don't break the edit 1-1000 workflow.

I missed how it would break the workflow, I don’t think it would? Also edit 1-1000 in history is already broken the same way edit 3 is.

Lmk if I missed something.

If not, we can include it or not — either way is ok, just let me know whether to go forward with review in light of this or wait.

@ChrisPenner

Copy link
Copy Markdown
Member Author

I was just thinking that if you're doing find; edit 1-1000 often you'd probably want to be able to press up to do it again rather than type out edit 1-1000, but I guess that's a question for Cody and Stew.

Either way, this diff is getting pretty big, and that feature can easily be added independently, so I think we should probably move on without it for now.

@ceedubs

ceedubs commented Dec 19, 2023

Copy link
Copy Markdown
Contributor

FWIW, I'm unlikely to hit up to try to run edit 1-1000 again. usually it's days later that I want to run it again, and since overshooting doesn't mess it up, it's a lot faster to type edit 1-1000000 than to run another find.

@aryairani

aryairani commented Dec 19, 2023

Copy link
Copy Markdown
Contributor

This is cool. I'm still reading through it, and it looks like I created a conflict by merging other stuff, but otherwise 👍
Also asked @hojberg to weigh in but agree ! is about as good as anything offhand.

@ChrisPenner

Copy link
Copy Markdown
Member Author

One possibility would be to sunset Globbing now that fzf is better integrated and use ? instead of !.
I don't think globbing is widely used, fzf is almost certainly a more adaptable and safer experience, so I doubt we'd get too much pushback, but I dunno 🤷🏼‍♂️ .

@ChrisPenner

Copy link
Copy Markdown
Member Author

Good catch @ceedubs , yeah as part of this feature I've found 3-4 commands which had arguments mis-labeled as "Required", push is one of them apparently.

@ChrisPenner

ChrisPenner commented Dec 20, 2023

Copy link
Copy Markdown
Member Author

I'll do a quick audit over all Required args to catch any more, I see there are some variants of push I need to catch too.

EDIT: Yup, found a bunch more

@ceedubs

ceedubs commented Dec 20, 2023

Copy link
Copy Markdown
Contributor

Thanks, Chris. I've pulled your changes, but I'm stuck in yaml land for a while, so I'm not sure if I'll get to take it for much of a second test spin today.

@aryairani

aryairani commented Dec 20, 2023

Copy link
Copy Markdown
Contributor

I definitely want the fzf support for missing Required args, but I’m uneasy about the ! syntax for optional args (support for optional args was a late addition), and not sure what to do about it. I think it could be painful to stop supporting later, and could introduce unexpected maintenance constraints, so we should think hard about it up front.

What would splitting it out of this PR look like, (ie auto fzf support for missing Required args vs support for missing Required or Optional args)?

What are other solutions to the issue @ceedubs described, which this fzf support for optional args addresses?

Also if we add the feature in the first merge, maybe _ rather than ! 🚲🙂

@ceedubs

ceedubs commented Dec 21, 2023

Copy link
Copy Markdown
Contributor

Doesn't need to hold up this PR, but dependents and dependencies are two other commands that it would be nice to have fzf completion on. If it's easier, it's probably fine if it's only supported for a single arg.

@ChrisPenner

ChrisPenner commented Dec 21, 2023

Copy link
Copy Markdown
Member Author

What would splitting it out of this PR look like, (ie auto fzf support for missing Required args vs support for missing Required or Optional args)?

It's easy to remove, and we can add it in later if we want; it just means that if removed it becomes impossible to fuzzy-select ANY of the optional args, and impossible to fuzzy-complete in situations where you want to complete a required arg that's followed by an optional arg.

E.g. if you have a two argument merge, the second argument is optional, so it's impossible to fuzzy-complete the first arg while specifying the second like merge ! /foo would let you do, and it's impossible to ever fuzzy-complete that second argument like merge /foo ! or merge ! ! would let you do.

@ChrisPenner

ChrisPenner commented Dec 21, 2023

Copy link
Copy Markdown
Member Author

@ceedubs Ah, looks like there are a bunch more commands without any argument types at all 🙃 , patched any I could find that were missing (including dependents/dependencies) 👍🏼

@ceedubs

ceedubs commented Dec 21, 2023

Copy link
Copy Markdown
Contributor

It looks like a no-arg docs still doesn't start up fzf (unless I've failed to build your latest changes).

@ChrisPenner ChrisPenner mentioned this pull request Dec 22, 2023
5 tasks
@aryairani

aryairani commented Dec 23, 2023

Copy link
Copy Markdown
Contributor

For optionals:

Is there some way we can just make fzf trigger when we try to tab-complete, instead of haskeline's completer? i.e. no special tokens and follow-up?

@ChrisPenner

Copy link
Copy Markdown
Member Author

For optionals:
Is there some way we can just make fzf trigger when we try to tab-complete, instead of haskeline's completer? i.e. no special tokens and follow-up?

I tried this in an earlier iteration and Haskeline doesn't really like it. I did get it working, but since fzf overwrites a lot of the screen-space I couldn't get it to show the argument you completed properly, it would mess up the whole line. It's probably possible, but I doubt we could get it to work consistently in every terminal editor and on Windows :'(

@aryairani

Copy link
Copy Markdown
Contributor

As of today the plan is to split off the ! fzf support for optional args to a separate PR and merge the fzf support for mandatory args.

@ceedubs

ceedubs commented Jan 3, 2024

Copy link
Copy Markdown
Contributor

I've been using a build off of this branch for a couple of days and it has been going really well. Admittedly I had forgotten about the ! support so only used it a couple of times.

@aryairani aryairani left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Over the finish line :DD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants