|
# Return immediately if not an interactive shell |
|
# ============================================== |
|
# |
|
# The ~/.bashrc startup file is supposed to be for interactive shells only. |
|
# |
|
# In this file, I call commands that assume we are in an interactive shell. These |
|
# commands can cause errors if this condition is not met. For example, `stty -ixon` |
|
# will cause the following error if called from a non-interactive shell. |
|
# |
|
# $ ssh myserver 'cat file.txt' |
|
# stty: 'standard input': Inappropriate ioctl for device |
|
# |
|
# For some strange reason, bash will source ~/.bashrc, |
|
# even though it is non-interactive, if it detects that its standard input is connected to a |
|
# network connection. |
|
# |
|
# [Why is bash sourcing .bashrc in non-interactive mode when working via ssh?]( |
|
# https://unix.stackexchange.com/q/587207 |
|
# ) |
|
# |
|
# That's why we added the following check for interactive shell. |
|
# |
|
# Update: Apparently many linux distributions provide `/etc/skel/.bashrc` that do this check. |
|
# |
|
# [Why does bashrc check whether the current shell is interactive?]( |
|
# https://unix.stackexchange.com/q/257571 |
|
# ) |
|
# |
|
# Not Fedora/RedHat though. (Todo: file bug) |
|
|
|
if [[ $- != *i* ]]; then return; fi |
|
|
|
|
|
# Based on Fedora's default .bashrc |
|
# ================================= |
|
|
|
# https://src.fedoraproject.org/rpms/bash/blob/rawhide/f/dot-bashrc |
|
# Except I moved PATH customizations out of this file back to where they used to be in ~/.bash_profile |
|
# I disagree with Fedora's move of PATH customizations from ~/.bash_profile to ~/.bashrc |
|
# https://src.fedoraproject.org/rpms/bash/c/739b272e5f5d10cf27a847a44d09eb7f4b6ec89b?branch=rawhide |
|
# Doing PATH customizations in ~/.bash_profile is the preferred best practice. |
|
# https://unix.stackexchange.com/a/26059 |
|
|
|
# Source global definitions |
|
if [ -f /etc/bashrc ]; then |
|
. /etc/bashrc |
|
fi |
|
|
|
# Enable extended glob patterns |
|
shopt -s extglob |
|
|
|
# Disable History Expansion |
|
# http://superuser.com/a/133782 |
|
# https://unix.stackexchange.com/q/436505 |
|
# Short equivalent: set +H |
|
set +o histexpand |
|
|
|
# Support multi-line history entries well |
|
# https://stackoverflow.com/a/17194155 |
|
# https://unix.stackexchange.com/a/109035 |
|
shopt -s lithist |
|
shopt -s cmdhist |
|
|
|
# Disable XON/XOFF flow control to free up Ctrl-S for forward-history-search |
|
# |
|
# The default readline binding for forward-search-history is Ctrl+S: |
|
# |
|
# $ bind -P | grep -E '^forward-search-history' |
|
# forward-search-history can be found on "\C-s". |
|
# |
|
# This, however, collides with the terminal's use of Ctrl+S for XON/XOFF flow control. |
|
# |
|
# Never have I had needed to hit Ctrl+S to stop the sender from transmitting, |
|
# or Ctrl+Q to resume transmitting. These key strokes were useful in the age |
|
# of teletypes, early terminals, and primitive terminal emulators with |
|
# no scrollback buffer on slow modem connection. At today's 1Mbps+ network speeds, |
|
# trying to control the sender's transmission flow by pressing Ctrl+S and Ctrl+Q |
|
# is futile. Modern terminal emulators have large scrollback buffers anyway, so |
|
# the need no longer exists. Or use a pager, like 'more' (or 'less'). |
|
# |
|
# We therefore disable XOFF/XON flow control so that readline's keybinding |
|
# for Ctrl+S will work. As a bonus, it frees up Ctrl+Q too. Feel free to bind |
|
# that to something useful. |
|
# |
|
# There's talk in some linux distributions of disabling this by default. |
|
# https://bugs.launchpad.net/ubuntu/+source/bash/+bug/80635/comments/12 |
|
# |
|
# Note: Disabling XOFF/XON flow control can cause 'Inappropriate ioctl for device' error |
|
# when set in a non-interactive shell. See https://stackoverflow.com/q/24623021 . |
|
# We're good though because we follow the best practice of testing for interactive |
|
# shell at the top of .bashrc. See https://superuser.com/a/183980 |
|
stty -ixon |
|
|
|
# When you press TAB after a variable holding a directory, expand it. |
|
# http://tiswww.case.edu/php/chet/bash/NEWS |
|
# http://askubuntu.com/questions/70750/how-to-get-bash-to-stop-escaping-during-tab-completion |
|
# http://stackoverflow.com/questions/6418493/bash-variable-expansion-on-tab-complete |
|
# https://bugs.launchpad.net/ubuntu/+source/bash/+bug/778627 |
|
# http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00274.html |
|
# http://nelsonslog.wordpress.com/2012/01/29/bash-4-2-variable-expansion-bug/ |
|
# https://unix.stackexchange.com/q/378625 |
|
shopt -s direxpand |
|
|
|
# Make cd smarter |
|
# So you never regret that you didn't use pushd |
|
cd() { |
|
if [[ $# == 0 ]]; then |
|
pushd "$HOME" >/dev/null |
|
elif [[ $1 == - ]]; then |
|
pushd >/dev/null |
|
else |
|
pushd "$@" >/dev/null |
|
fi |
|
} |
|
alias bk='popd >/dev/null' |
|
|
|
# Source user-specific bash completion scripts |
|
# ============================================ |
|
|
|
# Needed only on older systems. Modern bash-completion does this for us. |
|
|
|
if [[ ! $BASH_COMPLETION_VERSINFO ]]; then |
|
# We must be on an older system |
|
# We'll need to source our user-specific bash completion scripts ourselves |
|
if [[ -r ~/.local/share/bash-completion/completions ]]; then |
|
for rc in ~/.local/share/bash-completion/completions/*; do |
|
if [[ -f $rc ]]; then |
|
. "$rc" |
|
fi |
|
done |
|
fi |
|
fi |
|
|
|
# Disable beeping during TAB completion |
|
# https://unix.stackexchange.com/a/593495 |
|
bind 'set bell-style none' |
|
|
|
# It's better to put these keybindings in .inputrc so that they will apply to all |
|
# programs that use the readline library, not just bash. |
|
# I'm putting them here, too, in case you decide not to edit .inputrc. |
|
bind 'TAB:menu-complete' |
|
bind '"\e[A": history-search-backward' |
|
bind '"\e[B": history-search-forward' |