@@ -8,11 +8,9 @@ import (
88 "net/http"
99 "os"
1010 "os/exec"
11- "os/signal"
1211 "runtime"
1312 "strconv"
1413 "strings"
15- "syscall"
1614
1715 "github.com/cli/cli/api"
1816 "github.com/cli/cli/internal/ghinstance"
@@ -21,6 +19,7 @@ import (
2119 "github.com/cli/cli/pkg/iostreams"
2220 "github.com/cli/cli/utils"
2321 "github.com/spf13/cobra"
22+ "golang.org/x/term"
2423)
2524
2625type Geometry struct {
@@ -51,10 +50,11 @@ type Cell struct {
5150}
5251
5352const (
54- DirUp = iota
53+ DirUp Direction = iota
5554 DirDown
5655 DirLeft
5756 DirRight
57+ Quit
5858)
5959
6060type Direction = int
@@ -182,18 +182,6 @@ func gardenRun(opts *GardenOptions) error {
182182
183183 maxCommits := (geo .Width * geo .Height ) / 2
184184
185- sttyFileArg := "-F"
186- if runtime .GOOS == "darwin" {
187- sttyFileArg = "-f"
188- }
189-
190- oldTTYCommand := exec .Command ("stty" , sttyFileArg , "/dev/tty" , "-g" )
191- oldTTYSettings , err := oldTTYCommand .CombinedOutput ()
192- if err != nil {
193- fmt .Fprintln (out , "getting TTY settings failed:" , string (oldTTYSettings ))
194- return err
195- }
196-
197185 opts .IO .StartProgressIndicator ()
198186 fmt .Fprintln (out , "gathering commits; this could take a minute..." )
199187 commits , err := getCommits (httpClient , toView , maxCommits )
@@ -215,57 +203,42 @@ func gardenRun(opts *GardenOptions) error {
215203 clear (opts .IO )
216204 drawGarden (opts .IO , garden , player )
217205
218- // thanks stackoverflow https://stackoverflow.com/a/17278776
219- _ = exec .Command ("stty" , sttyFileArg , "/dev/tty" , "cbreak" , "min" , "1" ).Run ()
220- _ = exec .Command ("stty" , sttyFileArg , "/dev/tty" , "-echo" ).Run ()
221-
222- walkAway := func () {
223- clear (opts .IO )
224- fmt .Fprint (out , "\033 [?25h" )
225- _ = exec .Command ("stty" , sttyFileArg , "/dev/tty" , strings .TrimSpace (string (oldTTYSettings ))).Run ()
226- fmt .Fprintln (out )
227- fmt .Fprintln (out , cs .Bold ("You turn and walk away from the wildflower garden..." ))
206+ // TODO: use opts.IO instead of os.Stdout
207+ oldTermState , err := term .MakeRaw (int (os .Stdout .Fd ()))
208+ if err != nil {
209+ return fmt .Errorf ("term.MakeRaw: %w" , err )
228210 }
229211
230- c := make (chan os.Signal )
231- signal .Notify (c , os .Interrupt , syscall .SIGTERM )
212+ dirc := make (chan Direction )
232213 go func () {
233- <- c
234- walkAway ()
235- os .Exit (0 )
214+ b := make ([]byte , 3 )
215+ for {
216+ _ , _ = opts .IO .In .Read (b )
217+ switch {
218+ case isLeft (b ):
219+ dirc <- DirLeft
220+ case isRight (b ):
221+ dirc <- DirRight
222+ case isUp (b ):
223+ dirc <- DirUp
224+ case isDown (b ):
225+ dirc <- DirDown
226+ case isQuit (b ):
227+ dirc <- Quit
228+ }
229+ }
236230 }()
237231
238- var b [] byte = make ([] byte , 3 )
232+ mainLoop:
239233 for {
240- _ , _ = opts .IO .In .Read (b )
241-
242234 oldX := player .X
243235 oldY := player .Y
244- moved := false
245- quitting := false
246- continuing := false
247-
248- switch {
249- case isLeft (b ):
250- moved = player .move (DirLeft )
251- case isRight (b ):
252- moved = player .move (DirRight )
253- case isUp (b ):
254- moved = player .move (DirUp )
255- case isDown (b ):
256- moved = player .move (DirDown )
257- case isQuit (b ):
258- quitting = true
259- default :
260- continuing = true
261- }
262236
263- if quitting {
264- break
265- }
266-
267- if ! moved || continuing {
268- continue
237+ d := <- dirc
238+ if d == Quit {
239+ break mainLoop
240+ } else if ! player .move (d ) {
241+ continue mainLoop
269242 }
270243
271244 underPlayer := garden [player.Y ][player.X ]
@@ -315,7 +288,12 @@ func gardenRun(opts *GardenOptions) error {
315288 fmt .Fprint (out , cs .Bold (sl ))
316289 }
317290
318- walkAway ()
291+ clear (opts .IO )
292+ fmt .Fprint (out , "\033 [?25h" )
293+ // TODO: use opts.IO instead of os.Stdout
294+ _ = term .Restore (int (os .Stdout .Fd ()), oldTermState )
295+ fmt .Fprintln (out , cs .Bold ("You turn and walk away from the wildflower garden..." ))
296+
319297 return nil
320298}
321299
@@ -343,8 +321,10 @@ func isUp(b []byte) bool {
343321 return bytes .EqualFold (b , up ) || r == 'w' || r == 'k'
344322}
345323
324+ var ctrlC = []byte {0x3 , 0x5b , 0x43 }
325+
346326func isQuit (b []byte ) bool {
347- return rune (b [0 ]) == 'q'
327+ return rune (b [0 ]) == 'q' || bytes . Equal ( b , ctrlC )
348328}
349329
350330func plantGarden (commits []* Commit , geo * Geometry ) [][]* Cell {
0 commit comments