Skip to content

Instantly share code, notes, and snippets.

@vvvvv
Created March 3, 2024 08:04
Show Gist options
  • Save vvvvv/a7090a8da086284f6899cc9d87b6e54c to your computer and use it in GitHub Desktop.
Save vvvvv/a7090a8da086284f6899cc9d87b6e54c to your computer and use it in GitHub Desktop.
copy last command to clipboard unless it's a `cd`
#!/usr/bin/env zsh
# Copy the last command executed to the clipboard.
#
# Name this script copy_last_command and add it to your fpath.
# Add the following in your .zshrc to bind this script to Ctrl+Z.
#
# zle -N copy_last_command
# bindkey -M emacs '^Z' copy_last_command
# bindkey -M vicmd '^Z' copy_last_command
# bindkey -M viins '^Z' copy_last_command
typeset last_command
typeset -i ret=1
typeset -i max_nr_commands=100
typeset -i read_up_to_n_commands="$(fc -l 1 | head -n${max_nr_commands} | wc -l | tr -d '[:space:]')"
typeset -i current_history_search_depth=20
typeset -i inc_history_search_depth_by=20
_copy_to_clipboard() {
case "$(uname -s)" in
Linux*) xclip -selection c ;;
Darwin*) pbcopy ;;
CYGWIN*) cat >/dev/clipboard ;;
MINGW*) cat >/dev/clipboard ;;
*) cat > /dev/null ;;
esac
}
# go through the last `current_history_search_depth` history items
# by using a sliding window of `inc_history_search_depth_by` items
_maybe_find_cmd_from_history() {
local -i n
n="${1}"
while read -r c; do
last_command="${c}"
return 0
done < <(fc -lnr -${current_history_search_depth} | tail -n-${inc_history_search_depth_by} | awk '!/^cd/{ print $0 }' )
return 1
}
# check if last command in history is not `cd`
_maybe_get_cmd_from_history_fast() {
last_command="$(fc -ln -1 | awk '!/^cd/{ print $0 }')"
if [[ "${last_command:+x}" ]]; then
return 0
fi
return 1
}
# try to get the last command from the history which isn't a `cd` command
#
# first a fast path of using the last command is chosen.
# if this is a `cd` then batches of `inc_history_search_depth_by` are fetched and parsed
# this continues until `read_up_to_n_commands` is reached or a non `cd` command is found
_last_cmd_to_clipboard() {
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
if _maybe_get_cmd_from_history_fast; then
return 0
fi
while true; do
if [[ "${current_history_search_depth}" -gt "${read_up_to_n_commands}" ]]; then
return 1
fi
if _maybe_find_cmd_from_history ${current_history_search_depth} ; then
return 0
fi
current_history_search_depth=$((current_history_search_depth + inc_history_search_depth_by))
done
return 1
}
_last_cmd_to_clipboard "${@}"; ret=$?
if [[ "${ret}" -eq 0 ]]; then
echo -n "${last_command}" | _copy_to_clipboard
return 0
fi
return "${ret}"
#vim fd=zsh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment