Skip to content

Commit

Permalink
Migrated to using traps instead PROMPT_COMMAND
Browse files Browse the repository at this point in the history
- Created preexec.sh based off
  http://www.twistedmatrix.com/users/glyph/preexec.bash.txt. Eventually pull
  this into its own repo. Maybe use bpkg

- Redirected errors and stdout to log.txt
  • Loading branch information
rcaloras committed Nov 30, 2014
1 parent 3706cdb commit 9a113c3
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 29 deletions.
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include README.md
include bashhub/shell/*.sh
include bashhub/shell/*.zsh
include bashhub/shell/*.sh
include bashhub/shell/deps/*.sh
include bashhub/model/*
40 changes: 18 additions & 22 deletions bashhub/shell/bashhub.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
source ~/.bashhub/.config
source ~/.bashhub/lib-bashhub.sh
#
# bashhub.sh
# Main file that is sourced onto our path for Bash.
#

export BH_HOME_DIRECTORY="$HOME/.bashhub/"
export BH_EXEC_DIRECTORY="$HOME/.bashhub/env/bin"

# Alias to bind Ctrl + B
bind '"\C-b":"\C-u\C-kbh -i\n"'
BH_GET_LAST_COMMAND() {
# GRAB LAST OF COMMAND
local HISTORY_LINE=$(history 1)
local TRIMMED_COMMAND=`BH_TRIM_WHITESPACE $HISTORY_LINE`
local NO_LINE_NUMBER=`echo "$TRIMMED_COMMAND" | cut -d " " -f2-`
BH_TRIM_WHITESPACE $NO_LINE_NUMBER
}
BH_DEPS_DIRECTORY=$BH_HOME_DIRECTORY/deps

BH_ON_PROMPT_COMMAND() {
# Import our dependencies
if [[ -f $BH_DEPS_DIRECTORY/lib-bashhub.sh ]]; then
source $BH_DEPS_DIRECTORY/lib-bashhub.sh
fi

BH_PREV_COMMAND="$BH_COMMAND"
BH_COMMAND=$(BH_GET_LAST_COMMAND)
# Import prexec
if [[ -f $BH_DEPS_DIRECTORY/preexec.sh ]]; then
source $BH_DEPS_DIRECTORY/preexec.sh
preexec_install
fi

# Check to make sure we have a new command
if [[ "$BH_COMMAND" = "$BH_PREV_COMMAND" ]]; then
return 0
fi;
# Alias to bind Ctrl + B
bind '"\C-b":"\C-u\C-kbh -i\n"'

BH_PREEXEC "$BH_COMMAND"
preexec() {
BH_PREEXEC "$1" &> ~/.bashhub/log.txt
}

# Hook into Bash's PROMPT_COMMAND.
PROMPT_COMMAND="BH_ON_PROMPT_COMMAND; $PROMPT_COMMAND"

bh()
{
$BH_EXEC_DIRECTORY/bh "$@"
Expand Down
16 changes: 13 additions & 3 deletions bashhub/shell/bashhub.zsh
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
source ~/.bashhub/.config
source ~/.bashhub/lib-bashhub.sh
#
# bashhub.zsh
# Main file that is sourced onto our path for Zsh.
#

export BH_HOME_DIRECTORY="$HOME/.bashhub/"
export BH_EXEC_DIRECTORY="$HOME/.bashhub/env/bin"

BH_DEPS_DIRECTORY=$BH_HOME_DIRECTORY/deps

# Import our dependencies
if [[ -f $BH_DEPS_DIRECTORY/lib-bashhub.sh ]]; then
source $BH_DEPS_DIRECTORY/lib-bashhub.sh
fi


function bh_preexec() {
(BH_PREEXEC $1)
BH_PREEXEC $1 &> ~/.bashhub/log.txt
}

function bh_precmd() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

export PATH=$PATH:"$HOME/.bashhub/bin"

BH_INCLUDE() {
[[ -f "$1" ]] && source "$1"
}

# Include our user configuration
BH_INCLUDE ~/.bashhub/.config

#
# Prepare and send our command to be processed.
#
Expand Down
106 changes: 106 additions & 0 deletions bashhub/shell/deps/preexec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/bin/bash

# preexec.bash -- Bash support for ZSH-like 'preexec' and 'precmd' functions.

# The 'preexec' function is executed before each interactive command is
# executed, with the interactive command as its argument. The 'precmd'
# function is executed before each prompt is displayed.

# To use, in order:

# 1. source this file
# 2. define 'preexec' and/or 'precmd' functions (AFTER sourcing this file),
# 3. as near as possible to the end of your shell setup, run 'preexec_install'
# to kick everything off.

# Note: this module requires 2 bash features which you must not otherwise be
# using: the "DEBUG" trap, and the "PROMPT_COMMAND" variable. preexec_install
# will override these and if you override one or the other this _will_ break.

# This variable describes whether we are currently in "interactive mode";
# i.e. whether this shell has just executed a prompt and is waiting for user
# input. It documents whether the current command invoked by the trace hook is
# run interactively by the user; it's set immediately after the prompt hook,
# and unset as soon as the trace hook is run.
preexec_interactive_mode=""

# Default do-nothing implementation of preexec.
preexec() {
:
}

# Default do-nothing implementation of precmd.
precmd() {
:
}

# This function is installed as the PROMPT_COMMAND; it is invoked before each
# interactive prompt display. It sets a variable to indicate that the prompt
# was just displayed, to allow the DEBUG trap, below, to know that the next
# command is likely interactive.
preexec_invoke_cmd() {
last_hist_ent="$(history 1)";
precmd;
preexec_interactive_mode="on";
}

# This function is installed as the DEBUG trap. It is invoked before each
# interactive prompt display. Its purpose is to inspect the current
# environment to attempt to detect if the current command is being invoked
# interactively, and invoke 'preexec' if so.
preexec_invoke_exec() {
if [[ -n "$COMP_LINE" ]]
then
# We're in the middle of a completer. This obviously can't be
# an interactively issued command.
return
fi
if [[ -z "$preexec_interactive_mode" ]]
then
# We're doing something related to displaying the prompt. Let the
# prompt set the title instead of me.
return
else
# If we're in a subshell, then the prompt won't be re-displayed to put
# us back into interactive mode, so let's not set the variable back.
# In other words, if you have a subshell like
# (sleep 1; sleep 2)
# You want to see the 'sleep 2' as a set_command_title as well.
if [[ 0 -eq "$BASH_SUBSHELL" ]]
then
preexec_interactive_mode=""
fi
fi

if [[ "preexec_invoke_cmd" == "$BASH_COMMAND" ]]
then
# Sadly, there's no cleaner way to detect two prompts being displayed
# one after another. This makes it important that PROMPT_COMMAND
# remain set _exactly_ as below in preexec_install. Let's switch back
# out of interactive mode and not trace any of the commands run in
# precmd.

# Given their buggy interaction between BASH_COMMAND and debug traps,
# versions of bash prior to 3.1 can't detect this at all.
preexec_interactive_mode=""
return
fi

local hist_ent="$(history 1)";
local this_command="$(echo "$hist_ent" | sed -e "s/^[ ]*[0-9]*[ ]*//g")";

# If none of the previous checks have returned out of this function, then
# the command is in fact interactive and we should invoke the user's
# preexec hook with the running command as an argument.
if [ -n "$this_command" ]; then
preexec "$this_command";
fi
}

# Execute this to set up preexec and precmd execution.
preexec_install() {

# Finally, install the actual traps.
PROMPT_COMMAND="${PROMPT_COMMAND} preexec_invoke_cmd";
trap 'preexec_invoke_exec' DEBUG;
}
7 changes: 4 additions & 3 deletions install-bashhub.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ setup_bashhub_files () {

# Have to have this. Error out otherwise.
if [ -z "$bashprofile" ]; then
die "No bashfile (e.g. .profile, .bashrc, ect) could be found" 1
die "No bashfile (e.g. .profile, .bashrc, etc) could be found" 1
fi

mkdir ~/.bashhub
Expand All @@ -103,9 +103,10 @@ setup_bashhub_files () {
tar -xvf client.tar.gz
cd bashhub-client*

# Copy over our sh files
# Copy over our sh files.
cp bashhub/shell/bashhub.sh ~/.bashhub/
cp bashhub/shell/lib-bashhub.sh ~/.bashhub/
# Copy over our dependencies.
cp -r bashhub/shell/deps ~/.bashhub/

# Add our file to our bashprofile if it doesn't exist yet
if grep -q "source ~/.bashhub/bashhub.sh" $bashprofile
Expand Down

0 comments on commit 9a113c3

Please sign in to comment.