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
Complete list of available scripts for npm run/run-script command #2366
Conversation
Aside: it should be considered to update the whole npm completion for bash/zsh directly from
|
What does that thing actually do? The documentation is a bit sparse. Does it receive a full commandline (like e.g. "npm run-script ") and then offer all possibilities that can result from that? If that's the case, something like |
Hi @faho, I'm not sure, but I will dig into it and maybe come with another pull-request. I'm just concerned about loosing the command and command options descriptions with that approach. I will read more about fish completions. |
@faho This PR adds completions for scripts defined in your local project's "name": "my-node-library",
"version": "1.0.0",
"description": "Description goes here.",
"main": "index.js",
"scripts": {
"test": "npm run tap",
"tap": "NODE_ENV=development tap test.js"
}, @stefanmaric Good job, but more useful would be the script and the value. The following does it, feel free to readapt and PR again. command npm run | command tail -n +2 | command sed "s/^ *//" | while read -l name
read -l value
complete -c npm -n "__fish_npm_using_command run" -a (printf "%s " "$name") -d "$value"
end |
@bucaran I implemented your code. I had to add the Aside: I noticed that I have quite long npm scripts, fish seems to trim descriptions to fit terminal viewport, still hard to scan my scripts: Any suggestions on how to improve this? I might want to trim script value to a fixed length. |
In other hand, I was trying to translate I have no idea how to translate that little piece into fish, I expected it to simply be the whole command, but I tried and it didn't work. |
Just command npm run | command tail -n +2 | command sed "s/^ *//" | while read -l name
set -l trim 10
read -l value
complete -c npm -n "__fish_npm_using_command run" \
-a (printf "%s " "$name") -d (echo "$value" | cut -c1-$trim)
end
This probably. Also check out this bash/fish translation table.
|
Awesome @bucaran! I was just not sure if it was a great idea, but with your approval, there it is. I will keep digging if a completion using Thanks! |
There is probably an easier way 😅 @faho I don't know about hardcoding the trim factor, but in general LGTM. |
Yes, and no - while
My assumption is that the |
@faho Do you mean finding a way to reuse the |
I think so, only if it is suitable for fishshell (I'm not sure we can provide commands and options descriptions using I have been busy with some other stuff today and haven't had chance to dig deeper. |
Try this: function __fish_complete_npm
set -lx COMP_LINE (commandline -o)
set -lx COMP_CWORD (count (commandline -c))
set -lx COMP_POINT (expr length (commandline -c))
npm completion -- $COMP_LINE ^/dev/null
end
complete -f -c npm -a "(__fish_complete_npm)" This is a bit fiddly, but it almost works. The main issue is it's rather hard to detect if the cursor is directly after the last word (i.e. something like |
This seems to work: function __fish_complete_npm
set -lx COMP_LINE (commandline -o)
set -lx COMP_CWORD (count (commandline -c))
set -lx COMP_POINT (expr length (commandline -c))
# If the cursor is after the last word, the empty token won't be counted by `count`
if test (commandline -ct) = ""
set COMP_CWORD (expr $COMP_CWORD + 1)
set COMP_LINE $COMP_LINE ""
end
npm completion -- $COMP_LINE ^/dev/null
end
complete -f -c npm -a "(__fish_complete_npm)" |
Sorry, this one should work, please test! function __fish_complete_npm
set -lx COMP_LINE (commandline -o)
# bash starts arrays with 0
set -lx COMP_CWORD (expr (count $COMP_LINE) - 1)
set -lx COMP_POINT (expr length "$COMP_LINE")
# If the cursor is after the last word, the empty token will disappear in the expansion
if test (commandline -ct) = ""
set COMP_CWORD (expr $COMP_CWORD + 1)
set COMP_LINE $COMP_LINE ""
end
npm completion -- $COMP_LINE ^/dev/null
end
complete -f -c npm -a "(__fish_complete_npm)" Now, even if we do this we should probably keep some hand-rolled completions for the descriptions, but everything without one should go. |
Another small bug - when the cursor isn't at the end of the commandline, COMP_POINT was off: function __fish_complete_npm --description "Complete the commandline using npm's 'completion' tool"
# npm completion is bash-centric, so we need to translate fish's "commandline" stuff to bash's $COMP_* stuff
# COMP_LINE is an array with the words in the commandline
set -lx COMP_LINE (commandline -o)
# COMP_CWORD is the index of the current word in COMP_LINE
# bash starts arrays with 0, so subtract 1
set -lx COMP_CWORD (expr (count $COMP_LINE) - 1)
# COMP_POINT is the index of point/cursor when the commandline is viewed as a string
set -l cmd_to_point (commandline -oc)
set -lx COMP_POINT (expr length "$cmd_to_point")
# If the cursor is after the last word, the empty token will disappear in the expansion
# Readd it
if test (commandline -ct) = ""
set COMP_CWORD (expr $COMP_CWORD + 1)
set COMP_LINE $COMP_LINE ""
end
npm completion -- $COMP_LINE ^/dev/null
end
complete -f -c npm -a "(__fish_complete_npm)" If you're unsure how to test: Place that in "~/.config/fish/completions/npm.fish". Now my main concern is that I'm not sure if |
@faho |
So my current version is: function __fish_complete_npm --description "Complete the commandline using npm's 'completion' tool"
# npm completion is bash-centric, so we need to translate fish's "commandline" stuff to bash's $COMP_* stuff
# COMP_LINE is an array with the words in the commandline
set -lx COMP_LINE (commandline -o)
# COMP_CWORD is the index of the current word in COMP_LINE
# bash starts arrays with 0, so subtract 1
set -lx COMP_CWORD (math (count $COMP_LINE) - 1)
# COMP_POINT is the index of point/cursor when the commandline is viewed as a string
set -lx COMP_POINT (commandline -C)
# If the cursor is after the last word, the empty token will disappear in the expansion
# Readd it
if test (commandline -ct) = ""
set COMP_CWORD (math $COMP_CWORD + 1)
set COMP_LINE $COMP_LINE ""
end
npm completion -- $COMP_LINE ^/dev/null
end
complete -f -c npm -a "(__fish_complete_npm)" From my (limited) testing, it seems we get the run stuff for free with this, and fish is smart enough to coalesce duplicate completion options into one with a description, so I actually rather like this. |
@faho yes it works for me. And has some nice features not available so far with Not so good: option completion is poor. It suggest ALL options for ALL commands and doesn't distinct between long and short option arguments: npm actually kinda treats both as the same, And of course no descriptions. I believe it would still need all the code I think that implementing |
Most of it. As far as I can see, we can currently only remove __fish_npm_settings and the help completion (the
The major issue here is that the option completion is poor. Excepting upstream improvement (which would benefit all npm users), there's a few things we could do:
What do you think? |
@faho I was also thinking in the third option you propose, I was testing around but got weird behavior with the Using: function __fish_npm_needs_option
set -l DASH (commandline -ct)
if test $DASH != "-" -a $DASH != "--"
return 0
end
return 1
end EDIT: sorry about that non-sense function. I was expecting a and: function __fish_complete_npm --description "Complete the commandline using npm's 'completion' tool"
# npm completion is bash-centric, so we need to translate fish's "commandline" stuff to bash's $COMP_* stuff
# COMP_LINE is an array with the words in the commandline
set -lx COMP_LINE (commandline -o)
# COMP_CWORD is the index of the current word in COMP_LINE
# bash starts arrays with 0, so subtract 1
set -lx COMP_CWORD (math (count $COMP_LINE) - 1)
# COMP_POINT is the index of point/cursor when the commandline is viewed as a string
set -lx COMP_POINT (commandline -C)
# If the cursor is after the last word, the empty token will disappear in the expansion
# Readd it
if test (commandline -ct) = ""
set COMP_CWORD (math $COMP_CWORD + 1)
set COMP_LINE $COMP_LINE ""
end
npm completion -- $COMP_LINE ^/dev/null
end
complete -f -c npm -n '__fish_npm_needs_option' -a "(__fish_complete_npm)" and: command npm run | command tail -n +2 | command sed "s/^ *//" | while read -l name
set -l trim 20
read -l value
complete -f -c npm -n "__fish_npm_using_command run" -a (printf "%s " "$name") -d (echo "$value" | cut -c1-$trim)
complete -f -c npm -n "__fish_npm_using_command run-script" -a (printf "%s " "$name") -d (echo "$value" | cut -c1-$trim)
end And I opened an issue (npm/npm#9524), but look at what they answered me. :c |
Umh, you probably want some kind of pattern matching for that - currently the only way fish exposes it is via switch/case: function __fish_npm_needs_option
switch (commandline -ct)
case "-*"
return 0
end
return 1
end
That's the wrong way around, no? This only uses
That's.... not great. |
Sweet! That's way prettier... But...
I'm sorry that my code is so confusing. I used Any idea why some completions offered on |
You're looking for
Are all of them still offered? If so, that's probably a bug in fish proper. If not, that's to be expected, the other code doesn't offer all possibilities so there's no descriptions for the ones it doesn't. |
Damn, dummy me! I forgot everything in fish is a function and
Yes, they are all offered. That was the first thing I checked. EDIT: Just commenting: #complete -f -c npm -n 'not __fish_npm_needs_option' -a "(__fish_complete_npm)" I'm going to commit anyway in case you guys want to take a look. |
Humm... maybe there's an issue with sorting? Otherwise, could you remove __fish_npm_settings and other things without description? They are just useless cruft now. The rest looks good. |
Totally forgot. There it is now.
I found another case for that weird behavior: Notice how complete -f -c npm -n '__fish_npm_needs_command' -a 'adduser add-user login' -d 'Add a registry user account' |
I can reproduce that, but I can't see how this is the fault of this completion script - it seems to be a bug in fish-proper. So.. are you okay with me merging this, or do you want to work on it some more? |
read -l value | ||
complete -f -c npm -n "__fish_npm_using_command run" -a (printf "%s " "$name") -d (echo "$value" | cut -c1-$trim) | ||
complete -f -c npm -n "__fish_npm_using_command run-script" -a (printf "%s " "$name") -d (echo "$value" | cut -c1-$trim) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stefanmaric How about rewriting those two lines to?
for cmd in run run-script
complete -f -c npm -n "__fish_npm_using_command $cmd" -a (printf "%s " "$name") -d (echo "$value" | cut -c1-$trim)
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, wait a minute... I don't think that works like you think.
That command npm run | ...
stuff will be executed once, when the completion is auto-loaded! (Append echo "npm completions loaded" >&2
to npm.fish to see it)
Now, if I understand correctly, npm run
is dependent on the current directory, so it'll trim and complete only the first directory you call the completion in (for a given shell instance).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be something like
function __fish_npm_run
command npm run | command tail -n +2 | command sed "s/^ *//" | while read -l name
set -l trim 20
read -l value
echo "$value" | cut -c1-$trim | read -l value
printf "%s\t%s\n" $name $value
end
end
for c in run run-script
complete -f -c npm -n "__fish_npm_using_command $c" -a "(__fish_npm_run)"
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when the completion is auto-loaded!
Good call @faho
Now, if I understand correctly, npm run is dependent on the current directory, so it'll trim and complete only the first directory you call the completion in (for a given shell instance).
This is correct.
⬆︎ LGTM
@stefanmaric Ping 😄
* Better handling of `npm run` output
Hey guys, I pushed the fix for I think it is good now except for that bug with some descriptions present and some not. |
@faho probably you already got into this, but I will share it anyway: I created a dummy completion: # ~/.config/fish/completions/hue.fish
complete -f -c hue -a "run"
complete -f -c hue -a "run" -d "RUN FOREST, RUN!"
complete -f -c hue -a "reveal" -d "SHOW ME BABY!"
complete -f -c hue -a "reveal" Result: EDIT: misspelled Forrest, lol. So if fishshell is meant to merge completions, yes, it is failing. Using |
@stefanmaric Edge case. But yes, it would be nice if instead of overwriting the last completion it would some how "merge" them. |
That @bucaran, I actually saw @faho commenting on this very same thread:
I still don't get why, in |
Unfortunately, it appears it isn't. "assume", "ass", "u", "me", and all that. I'm going to try to play with it some more - it appears that it's no fault of this completion script, but maybe there's a workaround to be found (in e.g. reordering). |
Okay, I've played with this some more, and ordering definitely has an impact - if I put __fish_complete_npm (and the corresponding I still believe this is a bug in fish - at the least in the case where one call offers a description and another doesn't, it should pick the description. Anyway, regarding this script, we have a couple of options:
Frankly, everything but the last looks bad to me. |
# and: https://github.com/fish-shell/fish-shell/pull/2366 | ||
complete -f -c npm -n 'not __fish_npm_needs_option' -a "(__fish_complete_npm)" | ||
|
||
# list available npm scripts and their parial content |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: Partial
Merged now, thanks! Let's see what upstream does with the "completion" tool - it's a nice idea. |
It will complete available scripts for
npm run
/npm run-script command
in current project.