src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/cli/examples/e3bc/main.go (about) 1 // Command e3bc ("Elvish-editor-enhanced bc") is a wrapper for the bc command 2 // that uses Elvish's cli library for an enhanced CLI experience. 3 package main 4 5 import ( 6 "fmt" 7 "io" 8 "unicode" 9 10 "src.elv.sh/pkg/cli" 11 "src.elv.sh/pkg/cli/examples/e3bc/bc" 12 "src.elv.sh/pkg/cli/modes" 13 "src.elv.sh/pkg/cli/term" 14 "src.elv.sh/pkg/cli/tk" 15 "src.elv.sh/pkg/diag" 16 "src.elv.sh/pkg/ui" 17 ) 18 19 // A highlighter for bc code. Currently this just makes all digits green. 20 // 21 // TODO: Highlight more syntax of bc. 22 type highlighter struct{} 23 24 func (highlighter) Get(code string) (ui.Text, []ui.Text) { 25 t := ui.Text{} 26 for _, r := range code { 27 var style ui.Styling 28 if unicode.IsDigit(r) { 29 style = ui.FgGreen 30 } 31 t = append(t, ui.T(string(r), style)...) 32 } 33 return t, nil 34 } 35 36 func (highlighter) LateUpdates() <-chan struct{} { return nil } 37 38 func main() { 39 var app cli.App 40 app = cli.NewApp(cli.AppSpec{ 41 Prompt: cli.NewConstPrompt(ui.T("bc> ")), 42 Highlighter: highlighter{}, 43 CodeAreaBindings: tk.MapBindings{ 44 term.K('D', ui.Ctrl): func(tk.Widget) { app.CommitEOF() }, 45 term.K(ui.Tab): func(w tk.Widget) { 46 codearea := w.(tk.CodeArea) 47 if codearea.CopyState().Buffer.Content != "" { 48 // Only complete with an empty buffer 49 return 50 } 51 w, err := modes.NewCompletion(app, modes.CompletionSpec{ 52 Replace: diag.Ranging{From: 0, To: 0}, Items: candidates(), 53 }) 54 if err == nil { 55 app.PushAddon(w) 56 } 57 }, 58 }, 59 GlobalBindings: tk.MapBindings{ 60 term.K('[', ui.Ctrl): func(tk.Widget) { app.PopAddon() }, 61 }, 62 }) 63 64 bc := bc.Start() 65 defer bc.Quit() 66 67 for { 68 code, err := app.ReadCode() 69 if err != nil { 70 if err != io.EOF { 71 fmt.Println("error:", err) 72 } 73 break 74 } 75 bc.Exec(code) 76 } 77 }