From 3256258ebfc04f34116b84b0af83e27e2dfb7400 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sun, 11 Nov 2018 23:08:40 +0100 Subject: [PATCH 1/6] Count stashes via ZSH --- functions/vcs.zsh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 321a1502..bb877bec 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -96,11 +96,9 @@ function +vi-git-tagname() { # Show count of stashed changes # Port from https://github.com/whiteinge/dotfiles/blob/5dfd08d30f7f2749cfc60bc55564c6ea239624d9/.zsh_shouse_prompt#L268 function +vi-git-stash() { - local -a stashes - - if [[ -s "${vcs_comm[gitdir]}/refs/stash" ]] ; then - stashes=$(command git stash list 2>/dev/null | wc -l) - hook_com[misc]+=" $(print_icon 'VCS_STASH_ICON')${stashes// /}" + if [[ -s "${vcs_comm[gitdir]}/logs/refs/stash" ]] ; then + local -a stashes=( "${(@f)"$(<${vcs_comm[gitdir]}/logs/refs/stash)"}" ) + hook_com[misc]+=" $(print_icon 'VCS_STASH_ICON')${#stashes}" fi } From a90258a9ee6f2aa6e8b7d54c85499756fe5b4003 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sun, 11 Nov 2018 23:17:33 +0100 Subject: [PATCH 2/6] Avoid warning when inside of .git dir We cannot detect untracked files when we are inside of a .git directory. --- functions/vcs.zsh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index bb877bec..d525f815 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -8,6 +8,8 @@ set_default POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY false function +vi-git-untracked() { + [[ -z "${vcs_comm[gitdir]}" || "${vcs_comm[gitdir]}" == "." ]] && return + if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach --quiet --recursive 'command git ls-files --others --exclude-standard')" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true From 645b9746772a977c7ae03d5ed1d990e5e3ee9f3e Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Mon, 12 Nov 2018 00:13:35 +0100 Subject: [PATCH 3/6] Fix error if user cds into a .git directory In this case is was previously not possible to get the untracked status. Now we temporarily change the directory to the repo root folder and then get the list of untracked files. --- functions/vcs.zsh | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index d525f815..321424c6 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -8,17 +8,35 @@ set_default POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY false function +vi-git-untracked() { - [[ -z "${vcs_comm[gitdir]}" || "${vcs_comm[gitdir]}" == "." ]] && return - - if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach --quiet --recursive 'command git ls-files --others --exclude-standard')" != "" ]]; then + [[ -z "${vcs_comm[gitdir]}" ]] && return + + # If we are in a repos root folder, vcs_comm[gitdir] yields ".git". + # Inside the .git dir itself (and not a subdir of it) the variable + # yields ".". In any other case (either a subdirectory of .git or + # the repo itself), the value of vcs_comm[gitdir] is the absolute + # path to the .git directory. + # Therefore we can step up a directory, if we are inside the .git + # folder. And in any other case, use the parent directory of the + # gitdir. + local repoDir="." + # Getting the parent dir of the current dir "." is still ".", so + # is is safe to do this always. + [[ "${vcs_comm[gitdir]}" != ".git" ]] && repoDir="${vcs_comm[gitdir]:h}" + [[ "${vcs_comm[gitdir]}" == "." ]] && repoDir=".." + + if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(cd ${repoDir} && command git submodule foreach --quiet --recursive 'command git ls-files --others --exclude-standard')" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true - elif [[ "$(command git ls-files --others --exclude-standard)" != "" ]]; then + elif [[ "$(cd ${repoDir} && command git ls-files --others --exclude-standard)" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true else VCS_WORKDIR_HALF_DIRTY=false fi + + # If we are in any other directory than the repo root, we want + # to go back a directory. + [[ "${vcs_comm[gitdir]}" != ".git" ]] && cd - >/dev/null } function +vi-git-aheadbehind() { From a6e60def4ba8b5f97e1ae4af8147a61b321d5dbf Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Mon, 12 Nov 2018 00:15:52 +0100 Subject: [PATCH 4/6] Fix stashes display Changing directories while checking for untracked files broke the display of git stashes. The hook was not called any more. This is why we disabled checking for untracked files within a .git folder. --- functions/vcs.zsh | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 321424c6..4cd778a4 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -8,35 +8,19 @@ set_default POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY false function +vi-git-untracked() { - [[ -z "${vcs_comm[gitdir]}" ]] && return - - # If we are in a repos root folder, vcs_comm[gitdir] yields ".git". - # Inside the .git dir itself (and not a subdir of it) the variable - # yields ".". In any other case (either a subdirectory of .git or - # the repo itself), the value of vcs_comm[gitdir] is the absolute - # path to the .git directory. - # Therefore we can step up a directory, if we are inside the .git - # folder. And in any other case, use the parent directory of the - # gitdir. - local repoDir="." - # Getting the parent dir of the current dir "." is still ".", so - # is is safe to do this always. - [[ "${vcs_comm[gitdir]}" != ".git" ]] && repoDir="${vcs_comm[gitdir]:h}" - [[ "${vcs_comm[gitdir]}" == "." ]] && repoDir=".." - - if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(cd ${repoDir} && command git submodule foreach --quiet --recursive 'command git ls-files --others --exclude-standard')" != "" ]]; then + [[ -z "${vcs_comm[gitdir]}" || "${vcs_comm[gitdir]}" == "." ]] && return + # If we are in a .git folder, do not check for untracked files. + [[ "${PWD:A}" =~ "\.git/" ]] && return + + if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach --quiet --recursive 'command git ls-files --others --exclude-standard')" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true - elif [[ "$(cd ${repoDir} && command git ls-files --others --exclude-standard)" != "" ]]; then + elif [[ "$(command git ls-files --others --exclude-standard)" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true else VCS_WORKDIR_HALF_DIRTY=false fi - - # If we are in any other directory than the repo root, we want - # to go back a directory. - [[ "${vcs_comm[gitdir]}" != ".git" ]] && cd - >/dev/null } function +vi-git-aheadbehind() { From fd660f4b92dd255a785a444394a00e09589b873c Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Mon, 12 Nov 2018 00:24:29 +0100 Subject: [PATCH 5/6] Fix checking for untracked files Now the untracked files are always checked from the root folder of the repo. --- functions/vcs.zsh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 4cd778a4..6c9bd055 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -12,10 +12,24 @@ function +vi-git-untracked() { # If we are in a .git folder, do not check for untracked files. [[ "${PWD:A}" =~ "\.git/" ]] && return + # If we are in a repos root folder, vcs_comm[gitdir] yields ".git". + # Inside the .git dir itself (and not a subdir of it) the variable + # yields ".". In any other case (either a subdirectory of .git or + # the repo itself), the value of vcs_comm[gitdir] is the absolute + # path to the .git directory. + # Therefore we can step up a directory, if we are inside the .git + # folder. And in any other case, use the parent directory of the + # gitdir. + local repoDir="." + # Getting the parent dir of the current dir "." is still ".", so + # is is safe to do this always. + [[ "${vcs_comm[gitdir]}" != ".git" ]] && repoDir="${vcs_comm[gitdir]:A:h}" + [[ "${vcs_comm[gitdir]}" == "." ]] && repoDir="${PWD:A:h}" + if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach --quiet --recursive 'command git ls-files --others --exclude-standard')" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true - elif [[ "$(command git ls-files --others --exclude-standard)" != "" ]]; then + elif [[ "$(command git ls-files --others --exclude-standard "${repoDir}")" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true else From 6cfe8f8d965bfb6a1314b907e4ab970dd42d4188 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Mon, 12 Nov 2018 00:37:34 +0100 Subject: [PATCH 6/6] Add test for detecting untracked files from sibling folder --- test/segments/vcs-git.spec | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/segments/vcs-git.spec b/test/segments/vcs-git.spec index fed1df19..17a277fb 100755 --- a/test/segments/vcs-git.spec +++ b/test/segments/vcs-git.spec @@ -473,4 +473,21 @@ function testDetectingUntrackedFilesInNestedSubmodulesWork() { assertEquals "%K{002} %F{000} master ? %k%F{002}%f " "$(build_left_prompt)" } -source shunit2/shunit2 \ No newline at end of file +function testDetectingUntrackedFilesInCleanSubdirectoryWorks() { + local -a POWERLEVEL9K_LEFT_PROMPT_ELEMENTS + POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(vcs) + local POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY="true" + unset POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND + mkdir clean-folder + touch clean-folder/file.txt + mkdir dirty-folder + touch dirty-folder/file.txt + git add . 2>/dev/null + git commit -m "Initial commit" >/dev/null + touch dirty-folder/new-file.txt + cd clean-folder + source ${P9K_HOME}/powerlevel9k.zsh-theme + assertEquals "%K{002} %F{000} master ? %k%F{002}%f " "$(build_left_prompt)" +} + +source shunit2/shunit2