mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-09 20:44:03 -08:00
parent
e422e87384
commit
bb246377ce
|
@ -61,10 +61,12 @@ An alternative is to use the [Posh-Git segment][poshgit]
|
|||
- display_status: `boolean` - display the local changes or not - defaults to `false`
|
||||
- display_status_detail: `boolean` - display the local changes in detail or not - defaults to `true`
|
||||
- display_stash_count: `boolean` show stash count or not - defaults to `false`
|
||||
- display_worktree_count: `boolean` show worktree count or not - defaults to `false`
|
||||
- status_separator_icon: `string` icon/text to display between staging and working area changes - defaults to ` |`
|
||||
- local_working_icon: `string` - the icon to display in front of the working area changes - defaults to `\uF044`
|
||||
- local_staged_icon: `string` - the icon to display in front of the staged area changes - defaults to `\uF046`
|
||||
- stash_count_icon: `string` icon/text to display before the stash context - defaults to `\uF692`
|
||||
- worktree_count_icon: `string` icon/text to display before the worktree context - defaults to `\uF1BB`
|
||||
|
||||
### HEAD context
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ type environmentInfo interface {
|
|||
hasFilesInDir(dir, pattern string) bool
|
||||
hasFolder(folder string) bool
|
||||
getFileContent(file string) string
|
||||
getFoldersList(path string) []string
|
||||
getPathSeperator() string
|
||||
getCurrentUser() string
|
||||
isRunningAsRoot() bool
|
||||
|
@ -219,6 +220,21 @@ func (env *environment) getFileContent(file string) string {
|
|||
return string(content)
|
||||
}
|
||||
|
||||
func (env *environment) getFoldersList(path string) []string {
|
||||
defer env.tracer.trace(time.Now(), "getFoldersList", path)
|
||||
content, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var folderNames []string
|
||||
for _, s := range content {
|
||||
if s.IsDir() {
|
||||
folderNames = append(folderNames, s.Name())
|
||||
}
|
||||
}
|
||||
return folderNames
|
||||
}
|
||||
|
||||
func (env *environment) getPathSeperator() string {
|
||||
defer env.tracer.trace(time.Now(), "getPathSeperator")
|
||||
return string(os.PathSeparator)
|
||||
|
|
|
@ -20,6 +20,7 @@ type gitRepo struct {
|
|||
gitWorkingFolder string // .git working folder, can be different of root if using worktree
|
||||
isWorkTree bool
|
||||
gitRootFolder string // .git root folder
|
||||
worktreeCount int
|
||||
}
|
||||
|
||||
type gitStatus struct {
|
||||
|
@ -120,6 +121,10 @@ const (
|
|||
AheadColor Property = "ahead_color"
|
||||
// BranchMaxLength truncates the length of the branch name
|
||||
BranchMaxLength Property = "branch_max_length"
|
||||
// DisplayWorktreeCount show worktree count or not
|
||||
DisplayWorktreeCount Property = "display_worktree_count"
|
||||
// WorktreeCountIcon shows before the worktree context
|
||||
WorktreeCountIcon Property = "worktree_count_icon"
|
||||
)
|
||||
|
||||
func (g *git) enabled() bool {
|
||||
|
@ -189,6 +194,9 @@ func (g *git) string() string {
|
|||
if g.repo.stashCount != 0 {
|
||||
fmt.Fprintf(buffer, " %s%d", g.props.getString(StashCountIcon, "\uF692 "), g.repo.stashCount)
|
||||
}
|
||||
if g.repo.worktreeCount != 0 {
|
||||
fmt.Fprintf(buffer, " %s%d", g.props.getString(WorktreeCountIcon, "\uf1bb "), g.repo.worktreeCount)
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
|
@ -270,6 +278,9 @@ func (g *git) setGitStatus() {
|
|||
if g.props.getBool(DisplayStashCount, false) {
|
||||
g.repo.stashCount = g.getStashContext()
|
||||
}
|
||||
if g.props.getBool(DisplayWorktreeCount, false) {
|
||||
g.repo.worktreeCount = g.getWorktreeContext()
|
||||
}
|
||||
}
|
||||
|
||||
func (g *git) SetStatusColor() {
|
||||
|
@ -315,30 +326,30 @@ func (g *git) getGitHEADContext(ref string) string {
|
|||
ref = fmt.Sprintf("%s%s", branchIcon, ref)
|
||||
}
|
||||
// rebase
|
||||
if g.hasGitFolder("rebase-merge") {
|
||||
head := g.getGitFileContents("rebase-merge/head-name")
|
||||
if g.env.hasFolder(g.repo.gitWorkingFolder + "/rebase-merge") {
|
||||
head := g.getGitFileContents(g.repo.gitWorkingFolder, "rebase-merge/head-name")
|
||||
origin := strings.Replace(head, "refs/heads/", "", 1)
|
||||
origin = g.truncateBranch(origin)
|
||||
onto := g.getGitRefFileSymbolicName("rebase-merge/onto")
|
||||
onto = g.truncateBranch(onto)
|
||||
step := g.getGitFileContents("rebase-merge/msgnum")
|
||||
total := g.getGitFileContents("rebase-merge/end")
|
||||
step := g.getGitFileContents(g.repo.gitWorkingFolder, "rebase-merge/msgnum")
|
||||
total := g.getGitFileContents(g.repo.gitWorkingFolder, "rebase-merge/end")
|
||||
icon := g.props.getString(RebaseIcon, "\uE728 ")
|
||||
return fmt.Sprintf("%s%s%s onto %s%s (%s/%s) at %s", icon, branchIcon, origin, branchIcon, onto, step, total, ref)
|
||||
}
|
||||
if g.hasGitFolder("rebase-apply") {
|
||||
head := g.getGitFileContents("rebase-apply/head-name")
|
||||
if g.env.hasFolder(g.repo.gitWorkingFolder + "/rebase-apply") {
|
||||
head := g.getGitFileContents(g.repo.gitWorkingFolder, "rebase-apply/head-name")
|
||||
origin := strings.Replace(head, "refs/heads/", "", 1)
|
||||
origin = g.truncateBranch(origin)
|
||||
step := g.getGitFileContents("rebase-apply/next")
|
||||
total := g.getGitFileContents("rebase-apply/last")
|
||||
step := g.getGitFileContents(g.repo.gitWorkingFolder, "rebase-apply/next")
|
||||
total := g.getGitFileContents(g.repo.gitWorkingFolder, "rebase-apply/last")
|
||||
icon := g.props.getString(RebaseIcon, "\uE728 ")
|
||||
return fmt.Sprintf("%s%s%s (%s/%s) at %s", icon, branchIcon, origin, step, total, ref)
|
||||
}
|
||||
// merge
|
||||
if g.hasGitFile("MERGE_MSG") && g.hasGitFile("MERGE_HEAD") {
|
||||
icon := g.props.getString(MergeIcon, "\uE727 ")
|
||||
mergeContext := g.getGitFileContents("MERGE_MSG")
|
||||
mergeContext := g.getGitFileContents(g.repo.gitWorkingFolder, "MERGE_MSG")
|
||||
matches := findNamedRegexMatch(`Merge branch '(?P<head>.*)' into`, mergeContext)
|
||||
if matches != nil && matches["head"] != "" {
|
||||
branch := g.truncateBranch(matches["head"])
|
||||
|
@ -351,15 +362,15 @@ func (g *git) getGitHEADContext(ref string) string {
|
|||
// reverts then CHERRY_PICK_HEAD/REVERT_HEAD will not exist so we have to read
|
||||
// the todo file.
|
||||
if g.hasGitFile("CHERRY_PICK_HEAD") {
|
||||
sha := g.getGitFileContents("CHERRY_PICK_HEAD")
|
||||
sha := g.getGitFileContents(g.repo.gitWorkingFolder, "CHERRY_PICK_HEAD")
|
||||
icon := g.props.getString(CherryPickIcon, "\uE29B ")
|
||||
return fmt.Sprintf("%s%s onto %s", icon, sha[0:6], ref)
|
||||
} else if g.hasGitFile("REVERT_HEAD") {
|
||||
sha := g.getGitFileContents("REVERT_HEAD")
|
||||
sha := g.getGitFileContents(g.repo.gitWorkingFolder, "REVERT_HEAD")
|
||||
icon := g.props.getString(RevertIcon, "\uF0E2 ")
|
||||
return fmt.Sprintf("%s%s onto %s", icon, sha[0:6], ref)
|
||||
} else if g.hasGitFile("sequencer/todo") {
|
||||
todo := g.getGitFileContents("sequencer/todo")
|
||||
todo := g.getGitFileContents(g.repo.gitWorkingFolder, "sequencer/todo")
|
||||
matches := findNamedRegexMatch(`^(?P<action>p|pick|revert)\s+(?P<sha>\S+)`, todo)
|
||||
if matches != nil && matches["sha"] != "" {
|
||||
action := matches["action"]
|
||||
|
@ -389,25 +400,18 @@ func (g *git) hasGitFile(file string) bool {
|
|||
return g.env.hasFilesInDir(g.repo.gitWorkingFolder, file)
|
||||
}
|
||||
|
||||
func (g *git) hasGitFolder(folder string) bool {
|
||||
path := g.repo.gitWorkingFolder + "/" + folder
|
||||
return g.env.hasFolder(path)
|
||||
}
|
||||
|
||||
func (g *git) getGitFileContents(file string) string {
|
||||
path := g.repo.gitWorkingFolder + "/" + file
|
||||
content := g.env.getFileContent(path)
|
||||
return strings.Trim(content, " \r\n")
|
||||
func (g *git) getGitFileContents(folder, file string) string {
|
||||
return strings.Trim(g.env.getFileContent(folder+"/"+file), " \r\n")
|
||||
}
|
||||
|
||||
func (g *git) getGitRefFileSymbolicName(refFile string) string {
|
||||
ref := g.getGitFileContents(refFile)
|
||||
ref := g.getGitFileContents(g.repo.gitWorkingFolder, refFile)
|
||||
return g.getGitCommandOutput("name-rev", "--name-only", "--exclude=tags/*", ref)
|
||||
}
|
||||
|
||||
func (g *git) getPrettyHEADName() string {
|
||||
var ref string
|
||||
HEAD := g.getGitFileContents("HEAD")
|
||||
HEAD := g.getGitFileContents(g.repo.gitWorkingFolder, "HEAD")
|
||||
branchPrefix := "ref: refs/heads/"
|
||||
if strings.HasPrefix(HEAD, branchPrefix) {
|
||||
ref = strings.TrimPrefix(HEAD, branchPrefix)
|
||||
|
@ -462,7 +466,7 @@ func (g *git) parseGitStats(output []string, working bool) *gitStatus {
|
|||
}
|
||||
|
||||
func (g *git) getStashContext() int {
|
||||
stashContent := g.getGitFileContents("logs/refs/stash")
|
||||
stashContent := g.getGitFileContents(g.repo.gitRootFolder, "logs/refs/stash")
|
||||
if stashContent == "" {
|
||||
return 0
|
||||
}
|
||||
|
@ -470,6 +474,14 @@ func (g *git) getStashContext() int {
|
|||
return len(lines)
|
||||
}
|
||||
|
||||
func (g *git) getWorktreeContext() int {
|
||||
if !g.env.hasFolder(g.repo.gitRootFolder + "/worktrees") {
|
||||
return 0
|
||||
}
|
||||
worktreeFolders := g.env.getFoldersList(g.repo.gitRootFolder + "/worktrees")
|
||||
return len(worktreeFolders)
|
||||
}
|
||||
|
||||
func (g *git) parseGitStatusInfo(branchInfo string) map[string]string {
|
||||
var branchRegex = `^## (?P<local>\S+?)(\.{3}(?P<upstream>\S+?)( \[(?P<upstream_status>(ahead (?P<ahead>\d+)(, )?)?(behind (?P<behind>\d+))?(gone)?)])?)?$`
|
||||
return findNamedRegexMatch(branchRegex, branchInfo)
|
||||
|
|
|
@ -45,7 +45,7 @@ const (
|
|||
MappedLocationsEnabled Property = "mapped_locations_enabled"
|
||||
// StackCountEnabled enables the stack count display
|
||||
StackCountEnabled Property = "stack_count_enabled"
|
||||
// Maximum path depth to display whithout shortening
|
||||
// MaxDepth Maximum path depth to display whithout shortening
|
||||
MaxDepth Property = "max_depth"
|
||||
)
|
||||
|
||||
|
|
|
@ -49,6 +49,11 @@ func (env *MockedEnvironment) getFileContent(file string) string {
|
|||
return args.String(0)
|
||||
}
|
||||
|
||||
func (env *MockedEnvironment) getFoldersList(path string) []string {
|
||||
args := env.Called(path)
|
||||
return args.Get(0).([]string)
|
||||
}
|
||||
|
||||
func (env *MockedEnvironment) getPathSeperator() string {
|
||||
args := env.Called(nil)
|
||||
return args.String(0)
|
||||
|
|
|
@ -570,6 +570,12 @@
|
|||
"description": "Display the stash count or not",
|
||||
"default": false
|
||||
},
|
||||
"display_worktree_count": {
|
||||
"type": "boolean",
|
||||
"title": "Display Worktree Count",
|
||||
"description": "Display the worktree count or not",
|
||||
"default": false
|
||||
},
|
||||
"status_separator_icon": {
|
||||
"type": "string",
|
||||
"title": "Status Separator Icon",
|
||||
|
@ -592,7 +598,13 @@
|
|||
"type": "string",
|
||||
"title": "Stash Count Icon",
|
||||
"description": "The icon to display before the stash context",
|
||||
"default": "\uF692"
|
||||
"default": "\uF692 "
|
||||
},
|
||||
"worktree_count_icon": {
|
||||
"type": "string",
|
||||
"title": "Worktree Count Icon",
|
||||
"description": "The icon to display before the worktree context",
|
||||
"default": "\uF1bb "
|
||||
},
|
||||
"commit_icon": {
|
||||
"type": "string",
|
||||
|
|
Loading…
Reference in a new issue