Skip to content

Commit 266f995

Browse files
committed
update
1 parent 167e2d7 commit 266f995

File tree

7 files changed

+603
-287
lines changed

7 files changed

+603
-287
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
22
CURRENT_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
33

4-
ZSH_PROMPT_SETUP_SCRIPT := $(CURRENT_DIR)/zsh/prompt_goprompt_setup.zsh
4+
ZSH_PROMPT_SETUP_SCRIPT := $(CURRENT_DIR)/zsh/prompt_asynczle_setup.zsh
55

66
install:
77
go install ./cmd/goprompt

cmd/goprompt/main.go

Lines changed: 172 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,149 @@
11
package main
22

33
import (
4+
"EXP/pkg/shellout"
45
"context"
6+
"encoding/json"
57
"fmt"
6-
"github.com/codeskyblue/go-sh"
78
"github.com/spf13/cobra"
8-
"github.com/spf13/pflag"
99
"os"
1010
"strings"
1111
"sync"
12+
"time"
1213
)
1314

14-
type CobraCallbackE func(cmd *cobra.Command, args []string) error
15+
var bgctx = context.Background()
1516

1617
var (
1718
cmd = &cobra.Command{
18-
Use: "goprompt",
19-
PersistentPreRunE: bindEnvironmentFlags("GOPROMPT"),
19+
Use: "goprompt",
2020
}
21-
cmdQuery = &cobra.Command{
22-
Use: "query",
23-
RunE: cmdQueryExec,
24-
}
25-
26-
cmdQueryStatus = cmd.PersistentFlags().Int(
21+
flgCmdStatus = cmd.PersistentFlags().Int(
2722
"cmd-status", 0,
2823
"cmd status of previous command",
2924
)
30-
cmdQueryPreexecTS = cmd.PersistentFlags().String(
31-
"preexec-ts", "0",
25+
flgPreexecTS = cmd.PersistentFlags().Int(
26+
"preexec-ts", 0,
3227
"pre-execution timestamp to gauge how log execution took",
3328
)
3429
)
3530

3631
func init() {
37-
cmd.AddCommand(cmdQuery)
38-
32+
cmd.RunE = cmdExec
3933
}
4034

41-
func bindEnvironmentFlags(prefix string) CobraCallbackE {
42-
return func(cmd *cobra.Command, args []string) (outErr error) {
43-
cmd.Flags().VisitAll(func(f *pflag.Flag) {
44-
if !f.Changed {
45-
envKey := prefix + "_" + strings.ReplaceAll(f.Name, "-", "_")
46-
if value, ok := os.LookupEnv(strings.ToUpper(envKey)); ok {
47-
if err := cmd.Flags().Set(f.Name, value); err != nil {
48-
outErr = err
49-
return
50-
}
51-
}
52-
}
53-
})
54-
return nil
55-
}
56-
}
35+
// PROMPT PARTS:
36+
// (exit-status: if > 0)
37+
// (parent-process)
38+
// (hostname: if remote connection)
39+
// (current-dir-path)
40+
// (vsc-information)
41+
// (timestamp)
5742

58-
func cmdQueryExec(cmd *cobra.Command, args []string) error {
59-
if *cmdQueryStatus != 0 {
60-
printPart("st", fmt.Sprintf("%#v", *cmdQueryStatus))
43+
func cmdExec(cmd *cobra.Command, args []string) error {
44+
if *flgCmdStatus != 0 {
45+
printPart("st", fmt.Sprintf("%#v", *flgCmdStatus))
6146
}
6247

63-
wg := new(sync.WaitGroup)
48+
wg := new(WaitGroupDispatcher)
49+
defer wg.Wait()
6450

65-
wg.Add(1)
66-
go func() {
67-
defer wg.Done()
51+
wg.Dispatch(func() {
52+
homeDir := os.Getenv("HOME")
6853

6954
if wd, err := os.Getwd(); err == nil {
70-
printPart("wd", trimPathLast(wd, 2))
55+
wdh := strings.Replace(wd, homeDir, "~", 1)
56+
57+
printPart("wd_full", wdh)
58+
printPart("wd", trimPath(wdh))
7159
}
72-
}()
7360

74-
wg.Add(1)
75-
go func() {
76-
defer wg.Done()
61+
nowTS := time.Now()
62+
printPart("ts", nowTS.Format("15:04:05 01/02/06"))
7763

78-
if branch, err := sh.Command("git", "branch", "--show-current").Output(); err == nil {
79-
printPart("git_br", trim(string(branch)))
64+
if *flgPreexecTS != 0 {
65+
cmdTS := time.Unix(int64(*flgPreexecTS), 0)
66+
67+
diff := nowTS.Sub(cmdTS)
68+
printPart("ds", diff.Round(time.Second))
69+
}
70+
})
71+
72+
//wg.Dispatch(func() {
73+
// out, err := stringExec("git", "config", "--list")
74+
// printPart("debug_o", js(out))
75+
// if err != nil {
76+
// printPart("debug_e", js(err.Error()))
77+
// }
78+
//})
79+
80+
wg.Dispatch(func() {
81+
cwg := new(WaitGroupDispatcher)
82+
defer cwg.Wait()
83+
84+
if _, err := stringExec("git", "rev-parse", "--show-toplevel"); err == nil {
85+
printPart("vcs", "git")
86+
} else {
87+
return
8088
}
81-
}()
8289

83-
wg.Add(1)
84-
go func() {
85-
defer wg.Done()
90+
cwg.Dispatch(func() {
91+
if branch, err := stringExec("git", "branch", "--show-current"); err == nil {
92+
printPart("vcs_br", trim(string(branch)))
93+
}
94+
})
8695

87-
if status, err := sh.Command("git", "status", "--porcelain").Output(); err == nil {
88-
if len(status) > 0 {
89-
printPart("git_st", "dirty")
90-
} else {
91-
printPart("git_st", "clean")
96+
cwg.Dispatch(func() {
97+
if status, err := stringExec("git", "status", "--porcelain"); err == nil {
98+
if len(status) > 0 {
99+
printPart("vcs_dirty", 1)
100+
printPart("vcs_dirty_st", js(status))
101+
} else {
102+
printPart("vsc_dirty", 0)
103+
}
92104
}
105+
})
106+
})
107+
108+
wg.Dispatch(func() {
109+
cwg := new(WaitGroupDispatcher)
110+
defer cwg.Wait()
111+
112+
var stgPatchTop string
113+
var err error
114+
115+
if stgPatchTop, err = stringExec("stg", "top"); err == nil {
116+
printPart("stg", "1")
117+
printPart("stg_top", stgPatchTop)
118+
} else {
119+
return
93120
}
94-
}()
95121

96-
wg.Wait()
97-
return nil
98-
}
122+
cwg.Dispatch(func() {
123+
gitSHA, _ := stringExec("stg", "id")
124+
stgSHA, _ := stringExec("stg", "id", stgPatchTop)
99125

100-
func trimPathLast(s string, n int) string {
101-
return s
102-
}
126+
if gitSHA != stgSHA {
127+
printPart("stg_dirty", 1)
128+
} else {
129+
printPart("stg_dirty", 0)
130+
}
131+
})
103132

104-
func intMax(a, b int) int {
105-
if a > b {
106-
return a
107-
} else {
108-
return b
109-
}
110-
}
133+
cwg.Dispatch(func() {
134+
if stgPatchLen, err := stringExec("stg", "series", "-c"); err == nil {
135+
printPart("stg_qlen", stgPatchLen)
136+
}
137+
})
111138

112-
func trim(s string) string {
113-
return strings.Trim(s, "\n\t ")
139+
cwg.Dispatch(func() {
140+
if stgPatchPos, err := stringExec("stg", "series", "-cA"); err == nil {
141+
printPart("stg_qpos", stgPatchPos)
142+
}
143+
})
144+
})
145+
146+
return nil
114147
}
115148

116149
func printPart(name string, value interface{}) {
@@ -120,17 +153,79 @@ func printPart(name string, value interface{}) {
120153
fmt.Printf("%s\t%v\n", name, value)
121154
}
122155

123-
// PROMPT PARTS:
124-
// (exit-status: if > 0)
125-
// (parent-process)
126-
// (hostname: if remote connection)
127-
// (current-dir-path)
128-
// (vsc-information)
129-
// (timestamp)
156+
//------------------------------------------------------------------------------
130157

131158
func main() {
132159
err := cmd.ExecuteContext(context.Background())
133160
if err != nil {
134161
panic(err)
135162
}
136163
}
164+
165+
//------------------------------------------------------------------------------
166+
167+
type WaitGroupDispatcher struct {
168+
wg sync.WaitGroup
169+
}
170+
171+
func (d *WaitGroupDispatcher) Dispatch(fn func()) {
172+
d.wg.Add(1)
173+
go func() {
174+
defer d.wg.Done()
175+
fn()
176+
}()
177+
}
178+
179+
func (d *WaitGroupDispatcher) Wait() {
180+
d.wg.Wait()
181+
}
182+
183+
func stringExec(path string, args ...string) (string, error) {
184+
out, err := shellout.New(bgctx,
185+
shellout.Args(path, args...),
186+
shellout.EnvSet(map[string]string{
187+
"GIT_OPTIONAL_LOCKS": "0",
188+
}),
189+
).RunString()
190+
return trim(out), err
191+
}
192+
193+
func js(v interface{}) string {
194+
b, _ := json.Marshal(v)
195+
return string(b)
196+
}
197+
198+
func trimPath(s string) string {
199+
var out []string
200+
201+
parts := strings.Split(s, "/")
202+
for i, part := range parts {
203+
if i == len(parts)-1 {
204+
out = append(out, part)
205+
} else {
206+
out = append(out, part[0:intMin(len(part), 1)])
207+
}
208+
}
209+
210+
return strings.Join(out, "/")
211+
}
212+
213+
func intMax(a, b int) int {
214+
if a > b {
215+
return a
216+
} else {
217+
return b
218+
}
219+
}
220+
221+
func intMin(a, b int) int {
222+
if a < b {
223+
return a
224+
} else {
225+
return b
226+
}
227+
}
228+
229+
func trim(s string) string {
230+
return strings.Trim(s, "\n\t ")
231+
}

0 commit comments

Comments
 (0)