How do you override/remove default completions in fish shell? - fish

I am adding completions for a command's subcommand, however fish is retaining the built in completions for the base command, but those no longer apply for the subcommand. I want to disable those base command completions when using the subcommand.
So, to give a specific example, I am adding complete completions for the python3 -m venv command. As I stated, all the builtin python3 completions still show even though they no longer apply. So, when I type python3 -m venv -<TAB>, I get the completions I've added (good!), but also all the default completions too (bad).
So I have this code:
function __fish_python_using_command
# make sure that the command (minus the first item) matches argv
set cmd (commandline -opc)
if [ (count $cmd) -le (count $argv) ]
return 1
end
set idx (math (count $argv)+1)
if [ "$argv" = "$cmd[2..$idx]" ]
return 0
end
return 1
end
complete -f -c python3 -n '__fish_python_using_command -m venv' -s h -l help -d 'Display help creating virtual Python environments'
After running this, when I type when I type python3 -m venv -<TAB> I get:
The new auto complete I defined for --help (correct)
The base defined auto complete for -h (wrong)
All the other python3 base auto complete switches like -V from complete --command python3 --short-option 'V' --description 'Display version and exit' (I want to disable these)
I have considered using the -e flag to remove the defaults when you are in python3 -m venv mode, but that seems like the wrong way to go about it. I'm stumped. How would one disable all existing completions once a subcommand mode is entered? Or would this require a fundamental change to the way the python3 fish builtin completions are structured?

Fish loads completions from files in $fish_complete_path. This is a list of directories, like $PATH. Put your completions into a file named after the command with a ".fish" suffix in an earlier directory and it will take precedence.
E.g. ~/.config/fish/completions/python3.fish.

Related

Running sudo on user-defined functions in fish

» cat ~/.config/fish/config.fish
function take
command mkdir $argv;and cd $argv
end
function check
sudo dmesg -c>/dev/null;
make clean; make;
/usr/local/bin/kedr start $argv;
sudo insmod "$argv.ko"; sudo rmmod $argv;
/usr/local/bin/kedr stop
dmesg;
end
function sudo
if functions -q $argv[1]
set argv fish -c "$argv"
end
command sudo $argv
end
While running I get this error:
» sudo check "simple-no-macro"
fish: Unknown command 'check simple-no-macro'
fish:
check simple-no-macro
^
You've asked this on GitHub as well, so here's my answer from there:
The problem here is that the function you've defined isn't present in the new instance of fish you start.
You'd be better off defining the check function in a file saved in ~/.config/fish/functions/check.fish, which will then let the function work across instances.
Side note: bash does let you export functions across instances using environment variables, but both zsh and ksh use a similar method to fish - see Propagating shell functions from Unix Power Tools.

AutoLS for fish shell

I have an auto-ls script in my conf.d directory
function __autols_hook --description "Auto ls" --on-event fish_prompt
if test "$__autols_last" != (pwd)
if test "$HOME" = (pwd)
else
clear; ls;
# Show git information, and if it's not a git repo, throw error
# into /dev/null. Simples
git status 2>/dev/null
end
end
set -g __autols_last (pwd)
end
This works very well. However, I'd also like this to trigger when I hit enter, in the same pwd, but with no command.
I can't find a way to check if the enter key was pressed but no command
Change the binding for the [enter] key:
bind \cm 'set -l cmd (commandline); test -z "$cmd"; and set -g _empty_command yes; or set -g _empty_command no; commandline -f execute'
Now you can test $_empty_command in your fish_prompt event function. Note that [ctrl-j] also invokes the execute command so you should probably also bind \cj to the same code. But that's optional unless you have an unusual terminal config.

Where do I find alias arguments in fastlane?

In a fastlane project that I am taking over everything is run by command line (e.g. not fastfile). In this project (using fastlane 1.7) there are aliases used for arguments. Where would I go to find out what each of the aliases map to as far as fastlane commands? For example:
def build(Myapp, skip_profile)
if skip_profile || download_provisioning_profiles(MyApp)
build_cmd = "gym -a -r -s #{MyApp.name} -o ./build -n #{MyApp.ipa_name} --use_legacy_build_api"
system(build_cmd)
else
puts "Was unable to install provisioning profiles"
exit 1
end
end
Looking at this I am pretty sure that -o is the output but where would I look to find out explicitly what -a and -r and -s and -o are?
Run
fastlane gym --help
to get a list of all available options for the gym tool.

How to send data to command line after calling .sh file?

I want to install Anaconda through EasyBuild. EasyBuild is a software to manage software installation on clusters. Anaconda can be installed with sh Anaconda.sh.
However, after running I have to accept the License agreement and give the installation location on the command line by entering <Enter>, yes <Enter>, path/where/to/install/ <Enter>.
Because this has to be installed automatically I want to do the accepting of terms and giving the install location in one line. I tried to do it like this:
sh Anaconda.sh < <(echo) >/dev/null < <(echo yes) >/dev/null \
< <(echo /apps/software/Anaconda/1.8.0-Linux-x86_64/) > test.txt
From the test.txt I can read that the first echo works as <Enter>, but I can't figure out how to accept the License agreement, as it sees it now as not sending yes:
Do you approve the license terms? [yes|no]
[no] >>> The license agreement wasn't approved, aborting installation.
How can I send the yes correctly to the script input?
Edit: Sorry, I missed the part about having to enter more then one thing. You can take a look at writing expect scripts. thegeekstuff.com/2010/10/expect-examples. You may need to install it however.
You could try piping with the following command: yes yes | sh Anaconda.sh. Read the man pages for more information man yes.
Expect is a great way to go and probably the most error proof way. If you know all the questions I think you could do this by just writing a file with the answers in the correct order, one per line and piping it in.
That install script is huge so as long as you can verify you know all the questions you could give this a try.
In my simple tests it works.
I have a test script that looks like this:
#!/bin/sh
echo -n "Do you accept "
read ANS
echo $ANS
echo -n "Install path: "
read ANS
echo $ANS
and an answers file that looks like this:
Y
/usr
Running it like so works... perhaps it will work for your monster install file as well.
cat answers | ./test.sh
Do you accept Y
Install path: /usr
If that doesn't work then the script is likely flushing and you will have to use expect or pexpect.
Good luck!
Actually, I downloaded and looked at the anaconda install script. Looks like it takes command line arguments.
/bin/bash Anaconda-2.2.0-Linux-x86_64.sh -h
usage: Anaconda-2.2.0-Linux-x86_64.sh [options]
Installs Anaconda 2.2.0
-b run install in batch mode (without manual intervention),
it is expected the license terms are agreed upon
-f no error if install prefix already exists
-h print this help message and exit
-p PREFIX install prefix, defaults to /home/cody.stevens/anaconda
Use the -b and -p options...
so use it like so:
/bin/bash Anaconda-2.2.0-Linux-x86_64.sh -b -p /usr
Also of note.. that script explicitly says not to run with '.' or 'sh' but 'bash' so they must have some dependency on a feature of bash.
--
Cody

Cant access Coda application from command-line

I am having trouble accessing Coda from command-line. I installed the "command-line coda" plug-in, verified that my installation is in the correct location, yet I still can seem to access Coda. Coda sits in my "Applications" folder which is the default location for the plug-in.
Anyone have have this problem? Any tips? On the their site it is recommended that you change the path.
export CODEPATH=/Applications/Coda.app
So I included the above line in my .bash_profile which did not help.
$ Coda -v
-bash: Coda: command not found
Thanks for any direction you can provide.
The default way to open an application on a Mac is to use open -a AppName so you should be able to change your bash profile to use that:
$ open -a Coda
I've created a bash script (as opposed to using the plugin) that Gregory Tomlinson originally posted about (it looks like he's since taken it down but it looks like the following).
Create a new file in /bin called coda:
$ cd /bin
$ sudo touch coda
$ vim coda
Hit an i to enter insert mode. Then include the following code:
#! /bin/bash
if [ "$1" = "" ]; then
echo "Please specify a file to open or create"
exit 0
else
for ARG in $*
do
touch -a $ARG && open -a Coda $ARG
done
exit 0
fi
Save and quit (hit the esc to exit insert mode then type :w !sudo tee % >/dev/null followed by the return key, press L for load when prompted, then type :q to quit). Then give that file execute permissions:
$ chmod u+x coda
Start a new Terminal window and you should be able to use:
$ coda filename.foo
Or just:
$ coda
For some strange reason, my paid registered Coda 2 app just wouldn't open for me this morning. I found this terminal command that worked for me:
open -a Coda\ 2
You can also put the following in your ~/.bash_profile file:
alias coda='open -a "Coda 2"'
I had a similar problem. After installing the plug-in, I still couldn't launch coda from the command line. I took a closer look at /user/local/bin and somehow the permissions had gotten reset so I didn't have execute permissions for /user/local/bin.
I updated my permissions with:
sudo chmod o=rx,g=rx /usr/local/bin
This solved my problem. However, Coda won't launch if the specified file does not exist, which makes it hard to create a file from the command line.