1package ui23import (4 "strconv"56 tea "charm.land/bubbletea/v2"78 "src.rest/cat/012/internal/sheet"9 "src.rest/cat/012/internal/ui/findbar"10)1112// Find and replace is a bar on the context line (package findbar); here13// are its commands and what it asks of the model.1415func init() {16 register(17 &command{id: "edit.find", macro: macroView, title: "Find", desc: "Find text in the sheet as you type", run: func(m *Model) tea.Cmd {18 m.openFind(false)19 return nil20 }},21 &command{id: "edit.replace", macro: macroView, title: "Find and replace", desc: "Find text and replace it", run: func(m *Model) tea.Cmd {22 m.openFind(true)23 return nil24 }, answer: func(m *Model, text string) (tea.Cmd, error) {25 m.openFind(true)26 err := m.overlay.(*findbar.Bar).Answer(text)27 m.host().Leave()28 return nil, err29 }},30 )31 register(32 &command{id: "edit.find_next", title: "Find next", desc: "Go to the next match of the last search", run: func(m *Model) tea.Cmd {33 m.findAgain(1)34 return nil35 }},36 &command{id: "edit.find_prev", title: "Find previous", desc: "Go to the previous match of the last search", run: func(m *Model) tea.Cmd {37 m.findAgain(-1)38 return nil39 }},40 )41 keymap["ctrl+f"] = "edit.find"42 keymap["ctrl+h"] = "edit.replace"43}4445// findAgain goes to the next (d = 1) or previous (d = -1) match of the46// last search from the active cell, without opening the bar, as n and N47// do in vim and less.48func (m *Model) findAgain(d int) {49 if m.find == nil || !m.find.Searched() {50 m.note = "No search yet: " + m.shortcut("edit.find") + " finds"51 return52 }53 m.find.Again(d)54}5556// openFind opens the bar, keeping the last search. A multi-cell selection57// becomes the search scope, as Sheets' "specific range".58func (m *Model) openFind(replace bool) {59 f, ok := m.overlay.(*findbar.Bar)60 if !ok {61 f = m.find62 if f == nil {63 f = findbar.New(m.host())64 }65 var sel *sheet.Rect66 if m.hasRange() {67 r := m.selection()68 sel = &r69 }70 f.Reset(sel)71 f.Vim = m.prefs.vim72 m.clearSelection()73 m.openOverlay(f)74 }75 f.Open(replace)76}7778// found reports whether a is a match of the open find bar.79func (m *Model) found(a sheet.Addr) bool {80 f, ok := m.overlay.(*findbar.Bar)81 return ok && f.Found(m.sheet, a)82}8384// cellCount is n cells in words: "1 cell", "3 cells".85func cellCount(n int) string {86 if n == 1 {87 return "1 cell"88 }89 return strconv.Itoa(n) + " cells"90}