Reputation:
Environment: debian9+vim7.4.
cat .bashrc
add(){
echo $(expr $1 + $2)
}
Now edit a file in vim
add 1 5
Run it in command mode :w !bash
,an error occur.
bash: line 1: add: command not found
shell returned 127
1.add set shellcmdflag=-ic
in both /etc/vim/vimrc and .bashrc and .vimrc .
2.reboot
3.vim test.sh
enter into command mode
:verbose set shellcmdflag
shellcmdflag=-ic
Last set from ~/.vimrc
4.input two lines in test.sh
ls
add 5 6
:w !bash
a1.sh test.py
bash: line 2: add: command not found
shell returned 127
How to make both two lines executed?
:execute '! source ~/.bashrc; source '.expand('%:p')
can make both commands: ls
and add
run.
After rebooting,
1.add function can't be called from sh test.sh
?
sh test.sh
test.sh #it means that ls command executed
test.sh: 2: test.sh: add: not found #it means that add function can't be called from /etc/vim/vimrc or .bashrc or .vimrc.
2.add function can't be called from vim !bash %
?
test.sh #it means that ls command executed
test.sh: line 2: add: command not found #it means that add function can't be called from /etc/vim/vimrc or .bashrc or .vimrc.
[4]+ Stopped vim test.sh
Upvotes: 15
Views: 4133
Reputation: 7647
How to make both two lines be executed?
ls
add 5 6
This also works (with either shellcmdflag=-ic
or shellcmdflag=-c
) :
:w !bash -i
With this approach there is no need to include export -f add
in .bashrc
.
Why add function can't be called from vim with
!bash %
?
Assuming you have flags shellcmdflag=-c
you can do:
:!bash -i ./%
which is quite similar to the answer of exe.
Upvotes: 1
Reputation: 320
To add the line export -f add
in .bashrc file.
add(){
echo $(expr $1 + $2)
}
export -f add
Now source .bashrc
,every method can call add function from .bashrc properly.
Upvotes: 4
Reputation: 1141
I suppose this should solve it for you. It's more of a workaround than an explanation of you problem but it gets the job done
:execute '! source ~/.bashrc; source '.expand('%:p')
I'm just manually sourcing bashrc before calling the command. One possible explanation to your problem is if you are on a mac. As far as I know OSX don't source bashrc, they do source bash_profile though.
Upvotes: 1
Reputation: 172738
The problem is that Vim by default invokes a non-interactive shell, and .bashrc
(where you've defined your add
function) is only read for interactive shells.
You can instruct Vim to use an interactive shell:
:set shellcmdflag=-ic
This may make external command invocations slighly slower (due to the overhead in evaluating your Bash initializations).
Alternatively, you could define the function somewhere else, so it's always available (but there's no easy place like this; see man bash
, esp. the INVOCATION
section). Or turn the function into a separate script accessible from your PATH (e.g. ~/bin/add
).
Upvotes: 16
Reputation: 107
The problem is your function is limited to an interactive shell to execute it you have to do like this
:!bash -ic "add 1 2"
Upvotes: 5