Skip to content

Commit eb98658

Browse files
committed
POC working, migrate to rendering prompt in pure go
1 parent 266f995 commit eb98658

File tree

2 files changed

+138
-35
lines changed

2 files changed

+138
-35
lines changed

cmd/goprompt/main.go

Lines changed: 86 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/json"
77
"fmt"
88
"github.com/spf13/cobra"
9+
"io"
910
"os"
1011
"strings"
1112
"sync"
@@ -18,18 +19,56 @@ var (
1819
cmd = &cobra.Command{
1920
Use: "goprompt",
2021
}
21-
flgCmdStatus = cmd.PersistentFlags().Int(
22+
23+
cmdQuery = &cobra.Command{
24+
Use: "query",
25+
Short: "start the query that pulls data for the prompt",
26+
}
27+
flgQCmdStatus = cmdQuery.PersistentFlags().Int(
2228
"cmd-status", 0,
2329
"cmd status of previous command",
2430
)
25-
flgPreexecTS = cmd.PersistentFlags().Int(
31+
flgQPreexecTS = cmdQuery.PersistentFlags().Int(
2632
"preexec-ts", 0,
2733
"pre-execution timestamp to gauge how log execution took",
2834
)
35+
36+
cmdRender = &cobra.Command{
37+
Use: "render",
38+
Short: "render the prompt based on the results of query",
39+
}
2940
)
3041

3142
func init() {
32-
cmd.RunE = cmdExec
43+
cmdQuery.RunE = cmdQueryRun
44+
cmd.AddCommand(cmdQuery)
45+
46+
cmdRender.RunE = cmdRenderRun
47+
cmd.AddCommand(cmdRender)
48+
}
49+
50+
func cmdRenderRun(cmd *cobra.Command, args []string) error {
51+
if _, err := os.Stdin.Stat(); err != nil {
52+
fmt.Printf("%#v", err)
53+
}
54+
55+
out, err := io.ReadAll(os.Stdin)
56+
if err != nil {
57+
panic(err)
58+
}
59+
60+
lines := strings.Split(string(out), "\n")
61+
vals := make(map[string]string)
62+
for _, line := range lines {
63+
key, value, ok := strings.Cut(line, "\t")
64+
if ok {
65+
vals[key] = value
66+
}
67+
}
68+
69+
fmt.Printf("%#v\n", vals)
70+
fmt.Printf(">")
71+
return nil
3372
}
3473

3574
// PROMPT PARTS:
@@ -40,9 +79,9 @@ func init() {
4079
// (vsc-information)
4180
// (timestamp)
4281

43-
func cmdExec(cmd *cobra.Command, args []string) error {
44-
if *flgCmdStatus != 0 {
45-
printPart("st", fmt.Sprintf("%#v", *flgCmdStatus))
82+
func cmdQueryRun(cmd *cobra.Command, args []string) error {
83+
if *flgQCmdStatus != 0 {
84+
printPart("st", fmt.Sprintf("%#v", *flgQCmdStatus))
4685
}
4786

4887
wg := new(WaitGroupDispatcher)
@@ -61,8 +100,8 @@ func cmdExec(cmd *cobra.Command, args []string) error {
61100
nowTS := time.Now()
62101
printPart("ts", nowTS.Format("15:04:05 01/02/06"))
63102

64-
if *flgPreexecTS != 0 {
65-
cmdTS := time.Unix(int64(*flgPreexecTS), 0)
103+
if *flgQPreexecTS != 0 {
104+
cmdTS := time.Unix(int64(*flgQPreexecTS), 0)
66105

67106
diff := nowTS.Sub(cmdTS)
68107
printPart("ds", diff.Round(time.Second))
@@ -89,7 +128,19 @@ func cmdExec(cmd *cobra.Command, args []string) error {
89128

90129
cwg.Dispatch(func() {
91130
if branch, err := stringExec("git", "branch", "--show-current"); err == nil {
92-
printPart("vcs_br", trim(string(branch)))
131+
branch = trim(branch)
132+
if len(branch) > 0 {
133+
printPart("vcs_br", trim(branch))
134+
return
135+
}
136+
}
137+
138+
if branch, err := stringExec("git", "name-rev", "--name-only", "HEAD"); err == nil {
139+
branch = trim(branch)
140+
if len(branch) > 0 {
141+
printPart("vcs_br", trim(branch))
142+
return
143+
}
93144
}
94145
})
95146

@@ -103,17 +154,40 @@ func cmdExec(cmd *cobra.Command, args []string) error {
103154
}
104155
}
105156
})
157+
158+
cwg.Dispatch(func() {
159+
if status, err := stringExec("git", "rev-list", "--left-right", "--count", "HEAD...@{u}"); err == nil {
160+
parts := strings.SplitN(status, "\t", 2)
161+
if len(parts) < 2 {
162+
parts = []string{"0", "0"}
163+
}
164+
165+
printPart("vcs_log_ahead", parts[0])
166+
printPart("vcs_log_behind", parts[1])
167+
}
168+
})
106169
})
107170

108171
wg.Dispatch(func() {
172+
var err error
173+
109174
cwg := new(WaitGroupDispatcher)
110175
defer cwg.Wait()
111176

112-
var stgPatchTop string
113-
var err error
177+
var stgSeriesLen string
178+
if stgSeriesLen, err = stringExec("stg", "series", "-c"); err == nil {
179+
printPart("stg", "1")
180+
printPart("stg_qlen", stgSeriesLen)
181+
}
114182

183+
cwg.Dispatch(func() {
184+
if stgSeriesPos, err := stringExec("stg", "series", "-cA"); err == nil {
185+
printPart("stg_qpos", stgSeriesPos)
186+
}
187+
})
188+
189+
var stgPatchTop string
115190
if stgPatchTop, err = stringExec("stg", "top"); err == nil {
116-
printPart("stg", "1")
117191
printPart("stg_top", stgPatchTop)
118192
} else {
119193
return
@@ -129,18 +203,6 @@ func cmdExec(cmd *cobra.Command, args []string) error {
129203
printPart("stg_dirty", 0)
130204
}
131205
})
132-
133-
cwg.Dispatch(func() {
134-
if stgPatchLen, err := stringExec("stg", "series", "-c"); err == nil {
135-
printPart("stg_qlen", stgPatchLen)
136-
}
137-
})
138-
139-
cwg.Dispatch(func() {
140-
if stgPatchPos, err := stringExec("stg", "series", "-cA"); err == nil {
141-
printPart("stg_qpos", stgPatchPos)
142-
}
143-
})
144206
})
145207

146208
return nil

zsh/prompt_asynczle_setup.zsh

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,12 @@ typeset -g C_PROMPT_NEWLINE=$'\n%{\r%}'
4040

4141
typeset -g G_LAST_STATUS=0
4242
typeset -g G_PREEXEC_TS=0
43+
typeset -g G_ASYNC_DONE=0
4344

4445
typeset -gA G_PROMPT_PARTS=()
4546

47+
typeset -g G_LAST_PROMPT=""
48+
4649
#-------------------------------------------------------------------------------
4750

4851
__async_prompt_info() {
@@ -65,16 +68,36 @@ __prompt_rerender() {
6568
if [[ ${P[vcs]} == "git" ]]; then
6669
local git_dirty_marks=""
6770
if [[ -n ${P[vcs_dirty]} && ${P[vcs_dirty]} != "0" ]]; then
68-
git_dirty_marks=":&"
71+
git_dirty_marks="(&)"
72+
fi
73+
74+
local git_log_dir=""
75+
if [[ ${P[vcs_log_ahead]} -gt 0 || ${P[vcs_log_behind]} -gt 0 ]]; then
76+
git_log_dir=":[+${P[vcs_log_ahead]}:-${P[vcs_log_behind]}]"
6977
fi
7078

7179
prompt_parts_top+=(
72-
"{git:${P[vcs_br]}${git_dirty_marks}}"
80+
"{${git_dirty_marks}git:${P[vcs_br]}${git_log_dir}}"
7381
)
7482

7583
if [[ -n ${P[stg]} ]]; then
84+
local stg_dirty_marks=""
85+
if [[ -n ${P[stg_ditry]} && ${P[stg_dirty]} != "0" ]]; then
86+
stg_dirty_marks="(&)"
87+
fi
88+
89+
local stg_patch=""
90+
if [[ -n ${P[stg_top]} ]]; then
91+
stg_patch=":${P[stg_top]}"
92+
fi
93+
94+
local stg_pos=""
95+
if [[ ${P[stg_qpos]} -gt 0 || ${P[stg_qlen]} -gt 0 ]]; then
96+
stg_pos=":[${P[stg_qpos]:-0}/${P[stg_qlen]:-0}]"
97+
fi
98+
7699
prompt_parts_top+=(
77-
"{stg:${P[stg_top]}:${P[stg_qpos]}/${P[stg_qlen]}}"
100+
"{stg${stg_patch}${stg_pos}}"
78101
)
79102
fi
80103
fi
@@ -97,26 +120,39 @@ __prompt_rerender() {
97120
"[${P[ts]}]"
98121
)
99122

100-
local prompt_marker=">"
123+
local prompt_marker=""
101124
if [[ $KEYMAP == "vicmd" ]]; then
102-
prompt_marker="<"
125+
prompt_marker=""
126+
fi
127+
128+
local prompt_prefix=":?"
129+
if [[ $G_ASYNC_DONE -eq 1 ]]; then
130+
prompt_prefix="::"
103131
fi
104132

105133
local -a prompt_parts=()
106134
if [[ ${#prompt_parts_top[@]} -gt 0 ]]; then
107-
prompt_parts+=(":: ${(j. .)prompt_parts_top}")
135+
prompt_parts+=("${prompt_prefix} %F{yellow}${(j. .)prompt_parts_top}%f")
136+
else
137+
prompt_parts+=("${prompt_prefix} %F{yellow}-----------%f")
108138
fi
109139
if [[ ${#prompt_parts_bottom[@]} -gt 0 ]]; then
110-
prompt_parts+=(":: ${(j. .)prompt_parts_bottom}")
140+
prompt_parts+=("${prompt_prefix} %F{blue}${(j. .)prompt_parts_bottom}%f")
141+
else
142+
prompt_parts+=("${prompt_prefix} %F{blue}-----------%f")
111143
fi
112144
prompt_parts+=(
113-
"$prompt_marker "
145+
"%F{green}$prompt_marker%f "
114146
)
115147

116148
local BR=$C_PROMPT_NEWLINE
117149
PROMPT="$BR${(pj.$BR.)prompt_parts}"
118150

119-
zle && zle reset-prompt
151+
if [[ $PROMPT != $G_LAST_PROMPT ]]; then
152+
zle && zle .reset-prompt
153+
fi
154+
155+
G_LAST_PROMPT="$PROMPT"
120156
}
121157

122158
#-------------------------------------------------------------------------------
@@ -134,6 +170,9 @@ __prompt_precmd() {
134170
# reset prompt state
135171
G_PROMPT_PARTS=()
136172

173+
# set prompt status to rendering
174+
G_ASYNC_DONE=0
175+
137176
__zle_async_dispatch __zle_async_fd_handler __async_prompt_info
138177

139178
__prompt_rerender
@@ -149,10 +188,12 @@ __zle_async_fd_handler() {
149188
local ZLE_FD=$1
150189

151190
# read in all data that is available
152-
if ! IFS='' read -r ASYNC_RESULT <&"$ZLE_FD"; then
191+
if ! IFS=$'\n' read -r ASYNC_RESULT <&"$ZLE_FD"; then
153192
# select marks this fd if we reach EOF,
154193
# so handle this specially.
155194
__zle_async_detach "$ZLE_FD"
195+
G_ASYNC_DONE=1
196+
__prompt_rerender
156197
return 1
157198
fi
158199

@@ -197,8 +238,8 @@ __zle_async_detach() {
197238
#-------------------------------------------------------------------------------
198239

199240
prompt_asynczle_setup() {
200-
autoload -Uz +X add-zle-hook-widget 2>/dev/null
201241
autoload -Uz +X add-zsh-hook 2>/dev/null
242+
autoload -Uz +X add-zle-hook-widget 2>/dev/null
202243

203244
add-zsh-hook precmd __prompt_precmd
204245
add-zsh-hook preexec __prompt_preexec

0 commit comments

Comments
 (0)