summaryrefslogtreecommitdiff
path: root/internal/prompt/pwd.go
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2020-03-28 13:53:10 +0100
committerStefan Majewsky <majewsky@gmx.net>2020-03-28 13:53:10 +0100
commited2b9374599cc00467b1c27121318748cc0d3f49 (patch)
tree65e3200a0b69817b24ae772223d1d852a52458af /internal/prompt/pwd.go
parent1ff86053ddef8de3247909434e0bd7000c060f2a (diff)
downloadgofu-ed2b9374599cc00467b1c27121318748cc0d3f49.tar.gz
rename pkg/ to internal/
Diffstat (limited to 'internal/prompt/pwd.go')
-rw-r--r--internal/prompt/pwd.go157
1 files changed, 157 insertions, 0 deletions
diff --git a/internal/prompt/pwd.go b/internal/prompt/pwd.go
new file mode 100644
index 0000000..1b93987
--- /dev/null
+++ b/internal/prompt/pwd.go
@@ -0,0 +1,157 @@
+/*******************************************************************************
+*
+* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
+*
+* 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 <http://www.gnu.org/licenses/>.
+*
+*******************************************************************************/
+
+package prompt
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+//Directory contains all data about a directory that the prompt needs.
+type Directory struct {
+ Path string
+ DisplayPath string
+ InBuildTree bool
+ InRepoTree bool
+ Repo *gitRepo
+ NearestAccessiblePath string
+}
+
+//CurrentDirectory prepares a Directory struct for the current working
+//directory.
+func CurrentDirectory() Directory {
+ cwd, err := os.Getwd()
+ if err != nil {
+ cwd = filepath.Clean(os.Getenv("PWD"))
+ }
+ return NewDirectory(cwd)
+}
+
+//NewDirectory prepares a Directory struct for the given path.
+func NewDirectory(path string) (dir Directory) {
+ dir.Path = path
+ dir.DisplayPath = path
+
+ //check if path actually exists
+ dir.NearestAccessiblePath = findNearestAccessiblePath(dir.Path)
+ if dir.NearestAccessiblePath == dir.Path {
+ //marks that everything is okay existence-wise
+ dir.NearestAccessiblePath = ""
+
+ //display tag if below /x/build
+ if buildPath := os.Getenv("BUILD_ROOT"); buildPath != "" {
+ rel, _ := filepath.Rel(buildPath, dir.DisplayPath)
+ if !strings.HasPrefix(rel, "..") && rel != "." {
+ dir.InBuildTree = true
+ dir.DisplayPath = filepath.Join("/", rel)
+ }
+ }
+
+ //display tag if below /x/src
+ if gopath := os.Getenv("GOPATH"); gopath != "" {
+ repoPath := filepath.Join(gopath, "src")
+ rel, _ := filepath.Rel(repoPath, dir.DisplayPath)
+ if !strings.HasPrefix(rel, "..") && rel != "." {
+ dir.InRepoTree = true
+ dir.DisplayPath = rel
+ }
+ }
+
+ //strip $HOME prefix if applicable and desirable
+ dir.stripHomeDirFromDisplay()
+
+ //check if we are inside a Git repository
+ var err error
+ dir.Repo, err = findRepo(dir.Path)
+ handleError(err)
+ }
+
+ return
+}
+
+//This part can benefit from a "return" in the middle, so it's in a separate function.
+func (dir *Directory) stripHomeDirFromDisplay() {
+ if !strings.HasPrefix(dir.DisplayPath, "/") {
+ return
+ }
+
+ homePath := os.Getenv("HOME")
+ if homePath == "" {
+ return
+ }
+
+ rel, _ := filepath.Rel(homePath, dir.DisplayPath)
+ if rel == "." {
+ //do not display an empty DisplayPath if tags are displayed
+ if dir.InBuildTree || dir.InRepoTree {
+ return
+ }
+ rel = ""
+ }
+ if !strings.HasPrefix(rel, "..") {
+ dir.DisplayPath = rel
+ }
+}
+
+func findNearestAccessiblePath(path string) string {
+ _, err := os.Stat(path)
+ if err == nil {
+ return path
+ }
+ return findNearestAccessiblePath(filepath.Dir(path))
+}
+
+func getDirectoryField(dir Directory) string {
+ if dir.DisplayPath == "" {
+ return ""
+ }
+
+ txt := withColor("1;36", dir.DisplayPath)
+ if dir.NearestAccessiblePath == "" {
+ //cwd accessible -> highlight path elements inside the repo (if any)
+ if dir.Repo != nil && dir.Repo.RootPath != dir.Path {
+ rel, _ := filepath.Rel(dir.Repo.RootPath, dir.Path)
+ if strings.HasSuffix(dir.DisplayPath, rel) {
+ base := strings.TrimSuffix(dir.DisplayPath, rel)
+ txt = withColor("0;36", base) + withColor("1;36", rel)
+ }
+ }
+ } else {
+ //cwd inaccessible -> highlight inaccessible path elements
+ rel, _ := filepath.Rel(dir.NearestAccessiblePath, dir.Path)
+ txt = withColor("1;36", dir.NearestAccessiblePath+"/") + withColor("1;31", rel)
+ }
+
+ //apply tags
+ if dir.InRepoTree {
+ txt = withType("repo", txt)
+ }
+ if dir.InBuildTree {
+ txt = withType("build", txt)
+ }
+ return txt
+}
+
+func getDeletedMessageField(dir Directory) string {
+ if dir.NearestAccessiblePath == "" {
+ return ""
+ }
+ return withColor("1;41", "cannot stat cwd")
+}