cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / internal / ui / suggest / sheets.go
sheets.go 2.2K
1package suggest23import (4 "slices"5 "strconv"6 "strings"78 "src.rest/cat/012/internal/sheet"9)1011// Sheet names in formula suggestions: typing =Su offers Summary! with the12// functions and named ranges, and ='Q3 offers 'Q3 plan'!, quoted as a13// reference needs; the sheet the formula is on isn't, as its cells need14// no name, and neither are hidden sheets. Accepting one inserts the sheet15// and its "!"; an arrow then points into that sheet, as clicking its tab16// would, so the reference comes out as Summary!B3.1718// sheetSuggestion is the suggestion for sheet s.19func sheetSuggestion(s *sheet.Sheet) Suggestion {20 detail, desc := "sheet, empty", "Sheet "+s.Name()+", empty"21 if used, ok := s.UsedRange(); ok {22 detail = "sheet, " + used.String()23 desc = "Sheet " + s.Name() + ": " + used.String() + ", " + cellCount(s.Len())24 }25 return Suggestion{Name: sheet.QuoteSheet(s.Name()) + "!", Detail: detail, Desc: desc}26}2728// cellCount is n cells in words: "1 cell", "3 cells".29func cellCount(n int) string {30 if n == 1 {31 return "1 cell"32 }33 return strconv.Itoa(n) + " cells"34}3536// otherSheets are the sheets offered in formulas typed on sh: the37// visible ones but sh, whose cells need no sheet name.38func otherSheets(sh *sheet.Sheet) []*sheet.Sheet {39 return slices.DeleteFunc(sh.Book().Visible(), func(s *sheet.Sheet) bool { return s == sh })40}4142// sheetSuggestions lists the other visible sheets for w, a quoted name43// typed so far in upper case: those starting with it, then from two44// letters on, those containing it.45func sheetSuggestions(sh *sheet.Sheet, w string) []Suggestion {46 var prefix, inner []Suggestion47 for _, s := range otherSheets(sh) {48 name := strings.ToUpper(s.Name())49 switch {50 case strings.HasPrefix(name, w):51 prefix = append(prefix, sheetSuggestion(s))52 case len(w) >= 2 && strings.Contains(name, w):53 inner = append(inner, sheetSuggestion(s))54 }55 }56 return append(prefix, inner...)57}5859// trimSheetEnd drops the end of a sheet reference ("!" or "'!") that60// follows the caret, which an accepted sheet brings with it.61func trimSheetEnd(rest []rune) []rune {62 switch {63 case len(rest) > 0 && rest[0] == '!':64 return rest[1:]65 case len(rest) > 1 && rest[0] == '\'' && rest[1] == '!':66 return rest[2:]67 }68 return rest69}