terminal vim not loading .zshrc - vim

My terminal vim configuration is not loading the ~/.zshrc. Zsh is the environment login shell. What is the proper configuration for this situation?
Here are some measures I've already taken and since removed:
set shell=zsh
(uses zsh as shell but doesn't source the rc)
set shellcmdflag=-ci
(all output suspended)
cat ~/.zshenv
$ source ~/.zshrc
(many errors when opening vim)

The accepted answer doesn't work as expected. The actual solution should be putting the aliases and other ~/.zshrc content into ~/.zshenv. The only thing needed in ~/.vimrc is set shell=zsh without any flags.

From the manual:
Commands are first read from /etc/zshenv; this cannot be overridden.
[...]
Commands are then read from $ZDOTDIR/.zshenv. If the shell is a
login shell, commands are read from /etc/zprofile and then
$ZDOTDIR/.zprofile. Then, if the shell is interactive,
commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc. Finally,
if the shell is a login shell, /etc/zlogin and $ZDOTDIR/.zlogin are
read.
From what I understand,
set shell=zsh\ -i
should work.

I found an handy solution. As the only thing I really need is all my aliases, I added a function to my ~/.zshrc file:
function zshalias()
{
grep "^alias" ~/.zshrc > ~/.zshenv
}
Then execute source ~/.zshrc && zshalias.
In your vimrc you only need:
shell=zsh
Everything then works perfectly with no suspended tty output!

Related

My alias name is referring to old alias not a new one [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between .bashrc, .bash_profile, and .environment?
It seems that if I use
alias ls='ls -F'
inside of .bashrc on Mac OS X, then the newly created shell will not have that alias. I need to type bash again and that alias will be in effect.
And if I log into Linux on the hosting company, the .bashrc file has a comment line that says:
For non-login shell
and the .bash_profile file has a comment that says
for login shell
So where should aliases be written in? How come we separate the login shell and non-login shell?
Some webpage say use .bash_aliases, but it doesn't work on Mac OS X, it seems.
The reason you separate the login and non-login shell is because the .bashrc file is reloaded every time you start a new copy of Bash. The .profile file is loaded only when you either log in or use the appropriate flag to tell Bash to act as a login shell.
Personally,
I put my PATH setup into a .profile file (because I sometimes use other shells);
I put my Bash aliases and functions into my .bashrc file;
I put this
#!/bin/bash
#
# CRM .bash_profile Time-stamp: "2008-12-07 19:42"
#
# echo "Loading ${HOME}/.bash_profile"
source ~/.profile # get my PATH setup
source ~/.bashrc # get my Bash aliases
in my .bash_profile file.
Oh, and the reason you need to type bash again to get the new alias is that Bash loads your .bashrc file when it starts but it doesn't reload it unless you tell it to. You can reload the .bashrc file (and not need a second shell) by typing
source ~/.bashrc
which loads the .bashrc file as if you had typed the commands directly to Bash.
Check out http://mywiki.wooledge.org/DotFiles for an excellent resource on the topic aside from man bash.
Summary:
You only log in once, and that's when ~/.bash_profile or ~/.profile is read and executed. Since everything you run from your login shell inherits the login shell's environment, you should put all your environment variables in there. Like LESS, PATH, MANPATH, LC_*, ... For an example, see: My .profile
Once you log in, you can run several more shells. Imagine logging in, running X, and in X starting a few terminals with bash shells. That means your login shell started X, which inherited your login shell's environment variables, which started your terminals, which started your non-login bash shells. Your environment variables were passed along in the whole chain, so your non-login shells don't need to load them anymore. Non-login shells only execute ~/.bashrc, not /.profile or ~/.bash_profile, for this exact reason, so in there define everything that only applies to bash. That's functions, aliases, bash-only variables like HISTSIZE (this is not an environment variable, don't export it!), shell options with set and shopt, etc. For an example, see: My .bashrc
Now, as part of UNIX peculiarity, a login-shell does NOT execute ~/.bashrc but only ~/.profile or ~/.bash_profile, so you should source that one manually from the latter. You'll see me do that in my ~/.profile too: source ~/.bashrc.
From the bash manpage:
When bash is invoked as an
interactive login shell, or as a
non-interactive shell with the
--login option, it first reads and executes commands from the file
/etc/profile, if that file exists.
After reading that file, it looks for
~/.bash_profile, ~/.bash_login, and
~/.profile, in that order, and reads
and executes commands from the first
one that exists and is readable. The
--noprofile option may be used when the shell is started to inhibit this
behavior.
When a login shell exits, bash
reads and executes commands from the
file ~/.bash_logout, if it exists.
When an interactive shell that is not a login shell is started, bash
reads and executes commands from ~/.bashrc, if that file exists. This
may be inhibited by using the --norc option. The --rcfile file option
will force bash to read and execute commands from file instead of
~/.bashrc.
Thus, if you want to get the same behavior for both login shells and interactive non-login shells, you should put all of your commands in either .bashrc or .bash_profile, and then have the other file source the first one.
.bash_profile is loaded for a "login shell". I am not sure what that would be on OS X, but on Linux that is either X11 or a virtual terminal.
.bashrc is loaded every time you run Bash. That is where you should put stuff you want loaded whenever you open a new Terminal.app window.
I personally put everything in .bashrc so that I don't have to restart the application for changes to take effect.

How can I force nvim to source my .bash_profile when creating a terminal buffer?

From my testing, it's clear that nvim doesn't source your .bash_profile when opening a new terminal buffer. I would like to force this to happen every time a new terminal buffer is created.
To confirm this behavior:
open your .bash_profile in nvim
export a new variable like
ISSOURCED
write out the file
open a terminal buffer
run echo $ISSOURCED
I've also checked that bash is running in interactive mode (it is) by executing if tty -s; then echo interactive; fi, based on this answer
However it is not a login shell, based on executing shopt -q login_shell && echo 'Login shell' || echo 'Not login shell', based on this answer. This means that it would normally source $HOME/.bashrc. Unfortunately I keep my bashrc in a different location and source it from my .bash_profile, so it isn't being picked up.
See my answer below for my current workaround and information about why it's less than ideal.
Add this to your ~/.vimrc:
set shell=bash\ -l
When invoked with -l (--login), bash reads your ~/.profile at startup (among other files) and thus everything sourced from there.
When invoked with -i (--interactive), bash reads your ~/.bashrc at startup (among other files) and thus everything sourced from there.
$ man bash or :h shell and :h shellcmdflag for more info.
Taken from: https://stackoverflow.com/a/9092644/1071756
I set up a mapping to open a new terminal:
nnoremap <leader>z :new<CR>:terminal<CR>
To source my .bash_profile, I changed it to this:
nnoremap <leader>z :new<CR>:terminal<CR>source $HOME/.bash_profile<CR>c<CR>
The problem with this solution is that it breaks if you try to open a terminal buffer in any way other than with this mapping

How to set PATH in Knoppix?

I'm using knoppix 7.0.3 and trying to set the PATH environment variable. According to the official Ubuntu documentation, /etc/environment should be the preferred place for this. So I added these lines in the file:
JAVA_HOME="/usr/lib/jvm/java-6-sun"
GRAILS_HOME="/home/knoppix/grails"
PATH="${PATH}:${JAVA_HOME}/bin:${GRAILS_HOME}/bin"
But after rebooting the system, the file just reverted to the original one (I was using persistent storage).
Then after some Googling, I tried to edit ~/.profile like this:
export JAVA_HOME="/usr/lib/jvm/java-6-sun"
export GRAILS_HOME="/home/knoppix/grails"
export PATH=$PATH:$JAVA_HOME/bin:$GRAILS_HOME/bin
This time, the first two variables got set (echoed in console), but the PATH didn't. It was still the default one when I echoed. What's wrong?
Modify /etc/profile on the following line:
PATH=".:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
The problem is that your PATH is being overwritten during initialization of bash, after reading .profile.
From the manpage of bash:
When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.
...
When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.
From your experience, it is apparent that if .bashrc doesn't exist, bash is trying to set PATH to a default value (I would appreciate if someone confirms this).
As we discussed in the comments on your question, adding the export commands to .bashrc (and thus creating the file) solves the problem. Alternatively, you can add
source ~/.profile
to the end of your .bashrc file for the same effect.

How to make vim use the same environment as my login shell when running commands with "!"?

I use !ls to execute bash command. But after i have configured something like source ~/.usr_profile in ~/.profile file, vim won't source this file as well. So when i want to execute a function declared in usr_profile , i have to run :!source ~/.usr_profile && my_command. When i using this once or twice, it's ok. But when use it frequently, the my vimrc becomes messy.
Is there any better method to solve this problem.Thanks
Adding this line to your ~/.vimrc should solve your immediate problem:
set shell=bash\ -l
When invoked with -l (--login), bash reads your ~/.profile at startup (among other files) and thus everything sourced from there.
When invoked with -i (--interactive), bash reads your ~/.bashrc at startup (among other files) and thus everything sourced from there.
Try $ man bash or :h shell and :h shellcmdflag for more info.
As for the differences between login and non-login shell I must admit my ignorance. This answer on serverfault may help, it's interesting, anyway.
Append the following two lines to your .vimrc.
set shell=/bin/bash " use bash
set shellcmdflag="-ic" " flag passed to the shell to execute "!" and ":!" commands
P.S. It seems that the accepted answer may cause some problems when editing '.bash' files or execute a 'git commit', but I don't know why.

How can I debug the bash prompt?

I've been editing .bashrc files and other init files, and it seems that I've left behind a few code snippets or two that are causing a few errors at the prompt (e.g. file missing), but I can't find them.
How do I debug the prompt to find out what init scripts I've carelessly hacked?
Most of the shells have debug flags that show the commands being executed. Bash may even have one that shows a command before expansion of variables and after. Have you tried checking (I believe) -c -x or -X flags and see if they show the information you are looking for.
You can set them as first thing in the rc files (most global one) or just pass it down into bash command by invoking it from another shell.
In fact, if you invoke bash from another shell, you can also use script command to record everything you see and do into the file, which makes postmortem analysis so much easier.
Try invoking bash with the -x flag, then sourcing your .bashrc or .bash_profile or whatever you're using. That ought to be prolix enough to find your problem
ie:
bash -x
source .bashrc
The easiest way to get a clean initial state is to SSH into your current host, but instead of letting SSH launch your shell with default settings, you provide an explicit command which prevents .bashrc from being read.
ssh -tt localhost /bin/bash --norc
The -tt forces SSH to allocate a TTY, which is what would normally happen when you open a shell connection, but is not default when running an explicit command.
The --norc prevents bash from reading your settings file (since we want to do that ourselves).
You should now be at a bash prompt, in a clean environment. This is useful for examining what variable are set to before your .bashrc runs etc. Enable tracing and source your .bashrc:
set -x # Enable tracing
source .bashrc
Try to see where you've defined prompt - probably it in some dot file in your home directory:
grep PS1 ~/.*
You can see current value of prompt by just printing it:
echo $PS1
HTH
Check the .bash_history file in your home directory to find out what commands you have been running. If you used commands like vi filename to open the init scripts, it will find them in the command history.

Resources