From a3aab9b7ca3e8ecfa8093a5801ba0bc611699c86 Mon Sep 17 00:00:00 2001 From: Stefan Majewsky Date: Sat, 19 Aug 2017 19:20:50 +0200 Subject: prettyprompt: add repo status display --- pkg/prompt/git.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ pkg/prompt/main.go | 1 + pkg/prompt/pwd.go | 12 --------- 3 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 pkg/prompt/git.go (limited to 'pkg') diff --git a/pkg/prompt/git.go b/pkg/prompt/git.go new file mode 100644 index 0000000..20f9445 --- /dev/null +++ b/pkg/prompt/git.go @@ -0,0 +1,79 @@ +/******************************************************************************* +* +* Copyright 2017 Stefan Majewsky +* +* This program is free software: you can redistribute it and/or modify it under +* the terms of the GNU General Public License as published by the Free Software +* Foundation, either version 3 of the License, or (at your option) any later +* version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +* A PARTICULAR PURPOSE. See the GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +*******************************************************************************/ + +package prompt + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" +) + +//Returns empty string if `path` is not inside a Git repo. +func findRepoRootPath(path string) string { + _, err := os.Stat(filepath.Join(path, ".git")) + if err == nil { + return path + } + if path == "/" { + return "" + } + return findRepoRootPath(filepath.Dir(path)) +} + +func getRepoStatusField(repoRootPath string) string { + if repoRootPath == "" { + return "" + } + + bytes, err := ioutil.ReadFile(filepath.Join(repoRootPath, ".git/HEAD")) + if err != nil { + handleError(err) + return withType("git", withColor("1;41", "unknown")) + } + refSpec := strings.TrimSpace(string(bytes)) + + //is current HEAD detached? + if !strings.HasPrefix(refSpec, "ref: refs/") { + return formatRepoStatusField(withColor("1;41", "detached"), refSpec) + } + + //current HEAD is a ref + refSpec = strings.TrimPrefix(refSpec, "ref: ") + refSpecDisplay := strings.TrimPrefix(refSpec, "refs/") + refSpecDisplay = strings.TrimPrefix(refSpecDisplay, "heads/") + + //read file corresponding to refspec to find commit + bytes, err = ioutil.ReadFile(filepath.Join(repoRootPath, ".git", refSpec)) + commitID := strings.TrimSpace(string(bytes)) + if err != nil { + handleError(err) + commitID = withColor("1;41", "unknown") + } + + return formatRepoStatusField(refSpecDisplay, commitID) +} + +func formatRepoStatusField(refSpec, commitID string) string { + //shorten plain commit IDs from 40 to 10 bytes + if len(commitID) == 40 && !strings.Contains(commitID, "\x1B") { + commitID = commitID[0:10] + } + return withType("git", refSpec+"/"+commitID) +} diff --git a/pkg/prompt/main.go b/pkg/prompt/main.go index 728f2f2..f46a7e4 100644 --- a/pkg/prompt/main.go +++ b/pkg/prompt/main.go @@ -37,6 +37,7 @@ func Exec() int { cwd := CurrentDirectory() fields = appendUnlessEmpty(fields, getDirectoryField(cwd)) fields = appendUnlessEmpty(fields, getDeletedMessageField(cwd)) + fields = appendUnlessEmpty(fields, getRepoStatusField(cwd.RepoRootPath)) fields = appendUnlessEmpty(fields, getTerminalField()) line := strings.Join(fields, " ") diff --git a/pkg/prompt/pwd.go b/pkg/prompt/pwd.go index 1623a5f..969a8ce 100644 --- a/pkg/prompt/pwd.go +++ b/pkg/prompt/pwd.go @@ -116,18 +116,6 @@ func findNearestAccessiblePath(path string) string { return findNearestAccessiblePath(filepath.Dir(path)) } -//Returns empty string if `path` is not inside a Git repo. -func findRepoRootPath(path string) string { - _, err := os.Stat(filepath.Join(path, ".git")) - if err == nil { - return path - } - if path == "/" { - return "" - } - return findRepoRootPath(filepath.Dir(path)) -} - func getDirectoryField(dir Directory) string { if dir.DisplayPath == "" { return "" -- cgit v1.3.1