Two of the most common commands I run when I cd
into a directory are:
git status
(which i do through git-number)ls -lh
(aliased automatically asll
through fish)
- If this directory is not a git repo, then I usually am thinking of command 2.
- If however it is a git repository then
- I’d like to know if any files have been changed in this directory and
- which ones specifically (which is command 1).
Wouldn’t it be nice if I could just hit the ↩ (enter key) and have this automatically happen?
Solution for fish users
If you’re using fish, I got you covered:
# filename: fish/conf.d/magic-enter.fish
function magic-enter-cmd --description "Issue git status or ls on hitting enter in a dir"
set -l cmd ll
set -l is_git_repository (fish -c "git rev-parse --is-inside-work-tree >&2" 2>| grep true) # Special variable indicating git.
set -l in_root_folder (fish -c "git rev-parse --show-toplevel >&2" 2>| grep (pwd))
set -l repo_has_changes (git status -s --ignore-submodules=dirty)
if test -n "$is_git_repository"
if test -n "$in_root_folder"
if test -n "$repo_has_changes"
set cmd git-number
end
end
end
echo $cmd
end
function magic-enter
set -l cmd (commandline)
if test -z "$cmd"
commandline -r (magic-enter-cmd)
commandline -f suppress-autosuggestion
end
commandline -f execute
end
bind \r magic-enter
Solution for zsh users
If you’re using zsh, I adapted the native solution like so:
# filename: magic-enter.plugin.zsh
# Default commands
: ${MAGIC_ENTER_GIT_COMMAND:="git-number"} # run when in a git repository
: ${MAGIC_ENTER_OTHER_COMMAND:="ll"} # run anywhere else
magic-enter() {
# Only run MAGIC_ENTER commands when in PS1 and command line is empty
# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#User_002dDefined-Widgets
if [[ -n "$BUFFER" || "$CONTEXT" != start ]]; then
return
fi
is_git_repository=$(git rev-parse --is-inside-work-tree)
in_repo_root_folder=$(git rev-parse --show-toplevel)
repo_has_changes=$(git status -s --ignore-submodules=dirty)
if [ "$is_git_repository" = true ] && [ "$in_repo_root_folder" = $PWD ] && [ ! -z "$repo_has_changes" ]; then
BUFFER="$MAGIC_ENTER_GIT_COMMAND"
else
BUFFER="$MAGIC_ENTER_OTHER_COMMAND"
fi
}
# Wrapper for the accept-line zle widget (run when pressing Enter)
# If the wrapper already exists don't redefine it
(( ! ${+functions[_magic-enter_accept-line]} )) || return 0
case "$widgets[accept-line]" in
# Override the current accept-line widget, calling the old one
user:*) zle -N _magic-enter_orig_accept-line "${widgets[accept-line]#user:}"
function _magic-enter_accept-line() {
magic-enter
zle _magic-enter_orig_accept-line -- "$@"
} ;;
# If no user widget defined, call the original accept-line widget
builtin) function _magic-enter_accept-line() {
magic-enter
zle .accept-line
} ;;
esac
zle -N accept-line _magic-enter_accept-line
Remember to source this in your .zshrc
:
source magic-enter.plugin.zsh
Revisions
- Make a change to only check git status in a root folder.
- Reddit
/u/colemaker360
reminded me that the^/dev/null
redirect strategy is now deprecated with fish 3. - Redditor
/u/jblondreddit
pointed out that porcelain can be a slow. - Add solution for zsh users