diff --git a/gshmm.go b/gshmm.go index 9ec41ef..2dd0f0a 100644 --- a/gshmm.go +++ b/gshmm.go @@ -60,20 +60,13 @@ func readPDF(name string) (string, error) { // model offers the core of the state for the entire UI. type model struct { - filterInput textinput.Model // Fuzzy search interface - datasheets []datasheet // All datasheets under cwd - datasheetsView []string // Filtered view on all datasheets - datasheetViewport viewport.Model // Viewport for the PDF content -} + input textinput.Model // Fuzzy search interface -// datasheetNames lists all datasheet names. -func (m model) datasheetNames() []string { - // TODO: cache this somewhere, it's called several times... in the model? - var names []string - for _, datasheet := range m.datasheets { - names = append(names, datasheet.filename) - } - return names + datasheets []datasheet // All datasheets under cwd + datasheetNames []string // All datasheet names (caching) + filteredDatasheets []string // Filtered view on all datasheets + + datasheetViewport viewport.Model // Viewport for the PDF content } // datasheetFromName retrieves a datasheet via a name. @@ -98,7 +91,9 @@ func initialModel() model { input := textinput.New() input.Focus() - var ds []datasheet + var datasheets []datasheet + var datasheetNames []string + // TODO: handle error in interface? _ = filepath.Walk(".", func(path string, info os.FileInfo, err error) error { if err != nil { @@ -112,12 +107,15 @@ func initialModel() model { // we could run this in a goroutine somewhere // this currently slows down startup time contents, _ := readPDF(path) - d := datasheet{ + + datasheet := datasheet{ filename: name, absPath: path, contents: contents, } - ds = append(ds, d) + + datasheets = append(datasheets, datasheet) + datasheetNames = append(datasheetNames, name) } return nil @@ -125,14 +123,16 @@ func initialModel() model { // TODO: set width/heigh to match terminal viewp := viewport.New(60, 30) - viewp.SetContent(ds[len(ds)-1].contents) + selectedDatasheet := datasheets[len(datasheets)-1].contents + viewp.SetContent(selectedDatasheet) m := model{ - filterInput: input, - datasheets: ds, - datasheetViewport: viewp, + input: input, + datasheets: datasheets, + datasheetNames: datasheetNames, + filteredDatasheets: datasheetNames, + datasheetViewport: viewp, } - m.datasheetsView = m.datasheetNames() return m } @@ -149,29 +149,29 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { cmds []tea.Cmd ) - if m.filterInput.Focused() { - var matched []string + if m.input.Focused() { + var matchedDatasheets []string - search := m.filterInput.Value() + search := m.input.Value() if len(search) >= minCharsUntilFilter { - matches := fuzzy.Find(search, m.datasheetNames()) + matches := fuzzy.Find(search, m.datasheetNames) for _, match := range matches { - matched = append(matched, match.Str) + matchedDatasheets = append(matchedDatasheets, match.Str) } if len(matches) > 0 { - m.datasheetsView = matched + m.filteredDatasheets = matchedDatasheets } else { - m.datasheetsView = m.datasheetNames() + m.filteredDatasheets = m.datasheetNames } } else { - m.datasheetsView = m.datasheetNames() + m.filteredDatasheets = m.datasheetNames } // TODO: implement cursor for scrolling up/down filtered // results so we can view the PDF contents as desired // it's currently just the last one (closest to input) - lastdatasheet := m.datasheetsView[len(m.datasheetsView)-1] + lastdatasheet := m.filteredDatasheets[len(m.filteredDatasheets)-1] viewportText := m.datasheetFromName(lastdatasheet) m.datasheetViewport.SetContent(viewportText) } @@ -185,7 +185,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } } - m.filterInput, cmd = m.filterInput.Update(msg) + m.input, cmd = m.input.Update(msg) cmds = append(cmds, cmd) m.datasheetViewport, cmd = m.datasheetViewport.Update(msg) @@ -199,14 +199,14 @@ func (m model) View() string { body := strings.Builder{} // TODO: paginate / trim view to last 10 or something? - sheets := strings.Join(m.datasheetsView, "\n") + sheets := strings.Join(m.filteredDatasheets, "\n") // TODO: style further with lipgloss, e.g. borders, margins, etc. panes := lipgloss.JoinHorizontal(lipgloss.Left, sheets, m.datasheetViewport.View()) body.WriteString(panes) - body.WriteString("\n" + m.filterInput.View()) + body.WriteString("\n" + m.input.View()) return body.String() }