4 ms·
Thanks for the awesome fish shell – my beloved default. For improvements here are two things I wish where possible in fish: * The ability via a flag to say th
by thibran 9y ago
Thanks for the awesome fish shell – my beloved default.
For improvements here are two things I wish where possible in fish:
* The ability via a flag to say that a fish-function should not interpret passed function-arguments. This would enable us to pass e.g. URLs to a function without quote them, which is somewhat anointing right now. So this change would be a nice usability improvement.
* I would like to be able to write dynamic completions, containing of a key-value pair. The key should be displayed and if the user selects a completion-item, the corresponding value should be passed to a fish-function from which arbitrary actions could be triggered. Maybe supporting JSON input here would be nice too.
- faho 9y ago>* The ability via a flag to say that a fish-function should not interpret passed function-arguments. Note that functions already don't expand the passed arguments. Fish expands them _before_ executing the function, so what you are asking for is a major layering violation. E.g. you can do this: function a b $argv end function b string escape -- $argv end a 'something * with ? loads {} of $pecial char"acters' and the output will come out right. You only need to quote it once. >This would enable us to pass e.g. URLs to a function without quote them I'm assuming what you are asking for isn't _passing_ URLs to functions, but rather _pasting_ URLs into the commandline. In which case fish has a feature I like to call "magic paste". When you paste with an open single quote (`somecommand '`), it'll escape single quotes (and backslashes). So you type the closing single quote and your argument will be passed to the command you are calling as the exact text you pasted. >The key should be displayed and if the user selects a completion-item, the corresponding value should be passed to a fish-function from which arbitrary actions could be triggered. We have "descriptions" for completions, which will be displayed _alongside_ the argument (i.e. the "value"). To generate them dynamically, simply separate them with a tab character (`\t`) from the argument, and separate these pairs with newlines. So printf '%s\t%s\n' 'argument' 'description' 'argument2' 'description2' will be displayed as argument (description) argument2 (description2) We use this to great effect in numerous places. E.g. the git completions will offer commit hashes with the summary line as description, so when I type `git revert <TAB>` I get something like 0a129475 (Replace opts.stdout with opts.to_stdout) I'm not sure I like the idea of hiding the real argument from the user. >Maybe supporting JSON input here would be nice too. The best completions are those that actually call the stuff they are completing (because that makes them really reactive), and not many commandline tools actually generate JSON. Anything in particular you're thinking about here? (And now I'm hoping that HN doesn't hopelessly mangle this comment)
- thibran 9y ago# First Topic The idea would be to be able to write something like this: function yt --pure youtube-dl $argv end The parser should stop interpreting arguments after the yt function call and pass the args as strings to the function as before. Then such a call would be possible: yt https://www.youtube.com/watch?v=mqma6GpM7vM https://www.youtube.com/watch?v=mqma6GpM7vM # Second Topic I wrote a little utility [1] to quicker navigate on the file system. Right now I have two commands: m [folder] // goto highest ranked folder mm [folder] // list results for folder-keyword I would like to be able to write 'm foobar' and then press tab to get a vertical completion-list. When the user selects a completion-list-item I would like to pass the result-path to the cd command. Some time ago I tried to write such a completion, but failed – that's why I still use a separate mm-function to list search results. [1]: https://github.com/thibran/maybe https://github.com/thibran/maybe I think JSON might be a good choice here because it would simplify the interaction with the completion program for advanced completions. Passing all those flags – mixed with some other shell function calls – to the 'complete' program is a bit cumbersome. My dream would be to have something like 'complete -c maybe --json [maybe-flag-to-generate-json-output]' and handle everything inside the application. { "fish_completion_version": 1, "header": "optional, completion header", "orientation": "vertical", "on_single_result": "optional, choose-item or display-item", "arguments": [ { "item", "description", "optional return value, if empty return item" }], "item_handler": "optional, name of fish function to call on-item-chosen" } I know JSON is not something you want to assemble in a script, but all programming languages have support for it and it's easy to use.
- faho 9y ago>Then such a call would be possible: yt https://www.youtube.com/watch?v=mqma6GpM7vM https://www.youtube.com/watch?v=mqma6GpM7vM Okay, so I did understand what you are saying. Like I said, that's a rather large layering violation, since the function has nothing to do with the expansions happening on its arguments. They are expanded before they ever reach the function. It's essentially allowing functions to modify the syntax around them. How exactly would this treat e.g. yt $URL/somefile Would the variable still be expanded? Would an asterisk glob be? If I _did_ want it to expand something even though the function is declared "pure", how would that work? Now I couldn't be sure how my arguments would be interpreted, or I'd have to go checking for everything I invoke. I use youtube-dl myself quite often, and what I do is just type youtube-dl ' then press ctrl-v (which is a keybinding that uses xsel or pbpaste to get the clipboard contents and insert them into the commandline) or ctrl-shift-v (which is my terminal's paste binding). Then I press `'` again and can download the video. Additionally, it's looking like 3.0 will remove the `?` glob, which is the thing that is most annoying with URLs (though "&" is also a thing). > I would like to be able to write 'm foobar' and then press tab to get a vertical completion-list. When the user selects a completion-list-item I would like to pass the result-path to the cd command. I would assume the reason you failed is that the argument you want doesn't match the argument the user typed. Because fish's completions undergo filtering (with some fuzzy-matching, so e.g. `f_c_i` matches `fish_config_interactive`). Otherwise every completion script would have to implement that by itself, and consistently to not confuse people. For completions, that's the right thing to do. What you want, I'd argue, isn's a completion. What you want is a selection menu. Which could be implemented with fish's completion pager (we have an open issue about making it accessible to the outside), but isn't the same thing. JSON here is a red herring, since you don't just want to add items (with descriptions), but also control the behavior of the pager ("orientation" and "on_single_result"). That you could do just with arguments to this `select` command (`list_of_items | select --orientation=vertical --on-single=choose`).