github.com/grahambrereton-form3/tilt@v0.10.18/internal/hud/edits.go (about) 1 package hud 2 3 import ( 4 "fmt" 5 "path" 6 7 "github.com/windmilleng/tilt/internal/rty" 8 "github.com/windmilleng/tilt/pkg/model" 9 ) 10 11 type EditStatusLineComponent struct { 12 bs buildStatus 13 } 14 15 var _ rty.Component = &EditStatusLineComponent{} 16 17 func NewEditStatusLine(buildStatus buildStatus) rty.Component { 18 return &EditStatusLineComponent{ 19 bs: buildStatus, 20 } 21 } 22 23 func (esl *EditStatusLineComponent) Size(availWidth, availHeight int) (int, int, error) { 24 return availWidth, 1, nil 25 } 26 27 func (esl *EditStatusLineComponent) makeEditsComponents(width int) (rty.Component, rty.Component) { 28 var filenames, filenamesEtAl rty.Component 29 30 // fit as many filenames as possible into `width` 31 if len(esl.bs.edits) > 0 { 32 // technically this might be a multi-digit number and could lose digits as we make more filenames explicit, 33 // but close enough 34 spaceForFilenames := width - len(fmt.Sprintf(" (+%d more)", len(esl.bs.edits))) 35 36 edits := esl.bs.edits 37 s := "" 38 for len(edits) > 0 { 39 next := path.Base(edits[0]) 40 if s != "" { 41 next = " " + next 42 } 43 if len(next) <= spaceForFilenames { 44 spaceForFilenames -= len(next) 45 s += next 46 edits = edits[1:] 47 } else { 48 break 49 } 50 } 51 52 filenames = rty.TextString(s) 53 54 if len(edits) > 0 { 55 if len(s) == 0 { 56 filenamesEtAl = rty.TextString(fmt.Sprintf("%d files", len(edits))) 57 } else { 58 filenamesEtAl = rty.TextString(fmt.Sprintf(" (+%d more)", len(edits))) 59 } 60 } 61 } 62 return filenames, filenamesEtAl 63 } 64 65 func (esl *EditStatusLineComponent) buildStatusText() rty.Component { 66 return buildStatusCell(esl.bs) 67 } 68 69 func (esl *EditStatusLineComponent) buildAgeText() rty.Component { 70 return deployTimeCell(esl.bs.deployTime, esl.bs.defaultTextColor()) 71 } 72 73 func (esl *EditStatusLineComponent) rightPane() rty.Component { 74 l := rty.NewConcatLayout(rty.DirHor) 75 l.Add(esl.buildStatusText()) 76 l.Add(middotText()) 77 l.Add(esl.buildAgeText()) 78 return l 79 } 80 81 func (esl *EditStatusLineComponent) Render(w rty.Writer, width, height int) error { 82 offset := 0 83 allocated := 0 84 sb := rty.NewStringBuilder() 85 bs := esl.bs 86 87 if len(bs.edits) == 0 { 88 if bs.reason.Has(model.BuildReasonFlagInit) { 89 sb.Fg(cLightText).Text("FIRST BUILD ") 90 } else if bs.reason.Has(model.BuildReasonFlagCrash) { 91 sb.Fg(cLightText).Text("CRASH BUILD ") 92 } 93 } else { 94 sb.Fg(cLightText).Text("EDITED FILES ") 95 } 96 97 lhs := sb.Build() 98 99 lhsW, _, err := lhs.Size(width, 1) 100 if err != nil { 101 return err 102 } 103 allocated += lhsW 104 105 rhs := esl.rightPane() 106 rhsW, _, err := rhs.Size(width, 1) 107 if err != nil { 108 return err 109 } 110 allocated += rhsW 111 112 filenames, filenamesEtAl := esl.makeEditsComponents(width - allocated) 113 var filenamesW, filenamesEtAlW int 114 if filenamesEtAl != nil { 115 filenamesEtAlW, _, err = filenamesEtAl.Size(width, 1) 116 if err != nil { 117 return err 118 } 119 allocated += filenamesEtAlW 120 } 121 122 if filenames != nil && allocated < width { 123 filenamesW, _, err = filenames.Size(width-allocated, 1) 124 if err != nil { 125 return err 126 } 127 } 128 129 { 130 w, err := w.Divide(0, 0, width, 1) 131 if err != nil { 132 return err 133 } 134 w.RenderChild(lhs) 135 offset += lhsW 136 } 137 138 if filenames != nil && filenamesW > 0 { 139 w, err := w.Divide(offset, 0, filenamesW, 1) 140 if err != nil { 141 return err 142 } 143 w.RenderChild(filenames) 144 offset += filenamesW 145 } 146 147 if filenamesEtAl != nil { 148 w, err := w.Divide(offset, 0, filenamesEtAlW, 1) 149 if err != nil { 150 return err 151 } 152 w.RenderChild(filenamesEtAl) 153 } 154 155 { 156 w, err := w.Divide(width-rhsW, 0, rhsW, 1) 157 if err != nil { 158 return err 159 } 160 w.RenderChild(rhs) 161 } 162 163 return nil 164 }