cat / 012
clone

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

cat/module-path
012 / internal / ui / nblang.go
nblang.go 3.8K
1package ui23import (4 "slices"5 "strings"67 tea "charm.land/bubbletea/v2"89 "src.rest/cat/012/internal/sheet"10 "src.rest/cat/012/internal/ui/cmdhelp"11 "src.rest/cat/012/internal/ui/nbview"12)1314// What the code editor knows of nushell: nu itself, asked about the15// cell being written (nbview.Nu), with the notebook's own words, and16// F1's help on the command at the caret. nu is17// asked only where a cell could run without asking: not in 012 serve18// unless serve-shell allows it, not with shell = off, and not about a19// file from another computer until its cells are trusted. Otherwise,20// and while nu is missing, old or slow, the built-ins answer.2122// nbLangKey is what a notebook's words were worked out from.23type nbLangKey struct {24 s *sheet.Sheet25 state int // the workbook's state in its history26 words int // how many of nu's command names were known27}2829// nbLang is the session's questions to nu.30func (m *Model) nbLang() *nbview.NuSession {31 if m.nb.lang == nil {32 m.nb.lang = nbview.NewNuSession(m.runner())33 }34 return m.nb.lang35}3637// nbMayAsk reports whether nu may be asked about the cells: they could38// run without asking.39func (m *Model) nbMayAsk() bool {40 if m.shellOff() != "" {41 return false42 }43 return m.configString("shell", "ask") == "on" || m.macroTrusted() || !m.nb.fromFile && len(m.book().Macros()) == 044}4546// syncLang tells nu's questions about notebook s's view v whether they47// may be asked, and the notebook's words once they've changed.48func (m *Model) syncLang(s *sheet.Sheet, v *nbview.View) {49 m.nbLang().SetOn(m.nbMayAsk())50 lang, ok := v.Providers.Completer.(*nbview.Nu)51 key := nbLangKey{s, m.book().StateID(), len(m.nb.words)}52 if !ok || key == m.nb.langKey {53 return54 }55 m.nb.langKey = key56 words := m.nbWords(s)57 var names []string58 for _, w := range words {59 if name, ok := strings.CutPrefix(w.Text, "$"); ok && name != "selection" && name != "sheet." {60 names = append(names, name)61 }62 }63 lang.SetWords(names, words)64}6566// nbWords are the completions of notebook s's cells: its names, the67// workbook's regions, and nu's commands once they're known.68func (m *Model) nbWords(s *sheet.Sheet) []nbview.Word {69 var out []nbview.Word70 for _, c := range s.NotebookCells() {71 name := c.Name()72 if name != "" {73 out = append(out, nbview.Word{Text: "$" + name, Desc: "a cell's output"})74 }75 for _, n := range c.Parse().Assigned() {76 if n != name && !slices.ContainsFunc(out, func(w nbview.Word) bool { return w.Text == "$"+n }) {77 out = append(out, nbview.Word{Text: "$" + n, Desc: "a cell's variable"})78 }79 }80 }81 for _, t := range m.book().Sheets() {82 for _, r := range t.Regions() {83 if r.Linked() {84 out = append(out, nbview.Word{Text: "$" + r.Name, Desc: "linked file " + r.File.Path})85 }86 }87 }88 out = append(out, nbview.Word{Text: "$selection", Desc: "the selection on the sheet shown last"},89 nbview.Word{Text: "$sheet.", Desc: "a range of a sheet: $sheet.A1:C9"})90 for _, c := range m.nb.words {91 out = append(out, nbview.Word{Text: c, Desc: "command"})92 }93 return out94}9596func init() {97 register(&command{id: "nb.word_help", macro: macroNever, title: "Help on the command",98 desc: "Show the whole help of the nushell command or flag at the caret, with its page in nushell's docs",99 enabled: func(m *Model) bool { v := m.nbView(); return v != nil && v.Editing() },100 run: func(m *Model) tea.Cmd { return m.nbView().WordHelp() }})101}102103// showWordHelp opens the help of the command at the caret, or the104// keyboard shortcuts, as F1 anywhere else, when nu has none for it.105func (m *Model) showWordHelp(msg nbview.HelpMsg) tea.Cmd {106 if msg.Help == nil {107 return m.runCommand("help")108 }109 m.openOverlay(cmdhelp.New(m.host(), *msg.Help))110 return nil111}112113// Code draws a line of nushell as a notebook's cells do.114func (h host) Code(src string) string { return nbview.Highlighted(&h.m.th, src) }