-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] Enable zsh integration #107
Changes from 1 commit
f93be5e
3730839
3297785
4f34c9d
089ec6c
4da6f68
077595f
1c5e781
b168db1
3c07ce2
30e1df7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,7 @@ | ||
package integration | ||
|
||
var bashSource = ` | ||
# Be careful! This runs in the user shell. | ||
|
||
# Mask the command dad with this shell function | ||
# This let us mutate the current shell | ||
dad() { | ||
# Prepare a file to pass the finalize actions | ||
local finalizer_file | ||
finalizer_file="$(mktemp /tmp/dad-finalize-XXXXXX)" | ||
|
||
# Run the actual command | ||
env DAD_FINALIZER_FILE=$finalizer_file dad $@ | ||
return_code=$? | ||
|
||
# Perform finalizers | ||
local fin | ||
while read -r fin; do | ||
[ -n "${DAD_DEBUG:-}" ] && echo "DAD_DEBUG: finalizer: ${fin}" | ||
|
||
case "${fin}" in | ||
cd:*) | ||
cd "${fin//cd:/}" | ||
;; | ||
setenv:*) | ||
export "${fin//setenv:/}" | ||
;; | ||
*) | ||
;; | ||
esac | ||
done < "${finalizer_file}" | ||
rm -f "${finalizer_file}" | ||
|
||
return ${return_code} | ||
} | ||
|
||
__dad_prompt_command() { | ||
# In shell hook mode, the command will use stderr to print in the console | ||
# and stdout to mutate the shell (like activating a Python virtualenv) | ||
|
||
# Fail fast if no dad executable is reachable | ||
which dad > /dev/null || return | ||
|
||
local hook_eval | ||
hook_eval="$(command dad --shell-hook)" | ||
[ -n "${DAD_DEBUG:-}" ] && echo -e "DAD_DEBUG: Hook eval:\n${hook_eval}\n---" | ||
eval "${hook_eval}" | ||
} | ||
|
||
if [[ ! "${PROMPT_COMMAND:-}" == *__dad_prompt_command* ]]; then | ||
PROMPT_COMMAND="__dad_prompt_command; ${PROMPT_COMMAND:-}" | ||
fi | ||
|
||
dad-enable-debug() { | ||
export DAD_DEBUG=1 | ||
echo "DAD_DEBUG: enabled" | ||
} | ||
|
||
dad-disable-debug() { | ||
unset DAD_DEBUG | ||
echo "DAD_DEBUG: disable" | ||
} | ||
|
||
if [[ -n "${DAD_DEBUG:-}" ]]; then | ||
echo "DAD_DEBUG: Dad is now enabled..." | ||
fi | ||
` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package integration | ||
|
||
var shellSource = ` | ||
# Be careful! This runs in the user shell. | ||
|
||
# Mask the command dad with this shell function | ||
# This let us mutate the current shell | ||
dad() { | ||
# Prepare a file to pass the finalize actions | ||
local finalizer_file | ||
finalizer_file="$(mktemp /tmp/dad-finalize-XXXXXX)" | ||
|
||
# Run the actual command | ||
env DAD_FINALIZER_FILE=$finalizer_file dad $@ | ||
return_code=$? | ||
|
||
# Perform finalizers | ||
local fin | ||
while read -r fin; do | ||
[ -n "${DAD_DEBUG:-}" ] && echo "DAD_DEBUG: finalizer: ${fin}" | ||
|
||
case "${fin}" in | ||
cd:*) | ||
cd "${fin//cd:/}" | ||
;; | ||
setenv:*) | ||
export "${fin//setenv:/}" | ||
;; | ||
*) | ||
;; | ||
esac | ||
done < "${finalizer_file}" | ||
rm -f "${finalizer_file}" | ||
|
||
return ${return_code} | ||
} | ||
|
||
__dad_prompt_command() { | ||
# In shell hook mode, the command will use stderr to print in the console | ||
# and stdout to mutate the shell (like activating a Python virtualenv) | ||
|
||
# Fail fast if no dad executable is reachable | ||
which dad > /dev/null || return | ||
|
||
local hook_eval | ||
hook_eval="$(command dad --shell-hook)" | ||
[ -n "${DAD_DEBUG:-}" ] && echo -e "DAD_DEBUG: Hook eval:\n${hook_eval}\n---" | ||
eval "${hook_eval}" | ||
} | ||
|
||
dad-enable-debug() { | ||
export DAD_DEBUG=1 | ||
echo "DAD_DEBUG: enabled" | ||
} | ||
|
||
dad-disable-debug() { | ||
unset DAD_DEBUG | ||
echo "DAD_DEBUG: disable" | ||
} | ||
|
||
if [[ -n "${DAD_DEBUG:-}" ]]; then | ||
echo "DAD_DEBUG: Dad is now enabled..." | ||
fi | ||
` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,23 @@ package integration | |
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
color "github.com/logrusorgru/aurora" | ||
) | ||
|
||
func Print() { | ||
fmt.Println(bashSource) | ||
var currentShell = os.Getenv("SHELL") | ||
|
||
fmt.Println(shellSource) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we print most of the source already if we have a major failure condition right after? If we are running an unsupported shell, I think we should not print anything to stdout, because it will be eval'ed... by this unsupported shell. I know I mentioned the general idea of preferring warnings rather than stopping execution...(because it could partially work and that could be enough for some people) but in this case, it looks like it could actually be very dangerous... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah you're right it should work without shell integration but we should not have a half one |
||
|
||
if strings.HasSuffix(currentShell, "bash") { | ||
fmt.Println(bashSource) | ||
} else if strings.HasSuffix(currentShell, "zsh") { | ||
fmt.Println(zshSource) | ||
} else { | ||
fmt.Println(color.Brown("Your shell is not supported")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The execution context is an eval "$(dad --shell-init --with-completion)" So anything printed on the stdout will be eval'ed. |
||
} | ||
} | ||
|
||
func AddFinalizerCd(path string) error { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package integration | ||
|
||
var zshSource = ` | ||
prmptcmd() { $("__dad_prompt_command") } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to call the prompt command in a subshell with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes sadly it seems it needs to be called in a subshell cause if not, it would run as soon as you type |
||
precmd_functions=(prmptcmd) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could also be wrapped in a if statement in case dad is already activated
|
||
` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an idea, we could warn in case the value is empty, since it would be a very special case of "unknown shell".
That may help someone debug their environment someday.