diff --git a/ui/ui.go b/ui/ui.go index 3537d3f..d216b43 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -124,7 +124,9 @@ func (m *model) unloadDocument() []tea.Cmd { batch = append(batch, tea.ClearScrollArea) //nolint:staticcheck } - if !m.stash.shouldSpin() { + if !m.stash.loadingDone() && m.localFileFinder == nil { + batch = append(batch, findLocalFiles(*m.common), m.stash.spinner.Tick) + } else if !m.stash.shouldSpin() { batch = append(batch, m.stash.spinner.Tick) } return batch @@ -362,15 +364,7 @@ func findLocalFiles(m commonModel) tea.Cmd { err error ) - if cwd == "" { - cwd, err = os.Getwd() - } else { - var info os.FileInfo - info, err = os.Stat(cwd) - if err == nil && info.IsDir() { - cwd, err = filepath.Abs(cwd) - } - } + cwd, err = localFileSearchRoot(cwd) // Note that this is one error check for both cases above if err != nil { @@ -397,6 +391,21 @@ func findLocalFiles(m commonModel) tea.Cmd { } } +func localFileSearchRoot(path string) (string, error) { + if path == "" { + return os.Getwd() + } + + info, err := os.Stat(path) + if err != nil { + return "", err + } + if !info.IsDir() { + path = filepath.Dir(path) + } + return filepath.Abs(path) +} + func findNextLocalFile(m model) tea.Cmd { return func() tea.Msg { res, ok := <-m.localFileFinder diff --git a/ui/ui_test.go b/ui/ui_test.go new file mode 100644 index 0000000..367aa4e --- /dev/null +++ b/ui/ui_test.go @@ -0,0 +1,76 @@ +package ui + +import ( + "os" + "path/filepath" + "testing" + + tea "github.com/charmbracelet/bubbletea" +) + +func TestLocalFileSearchRootUsesParentDirectoryForFiles(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "index.md") + if err := os.WriteFile(path, []byte("# Test\n"), 0o600); err != nil { + t.Fatal(err) + } + + got, err := localFileSearchRoot(path) + if err != nil { + t.Fatal(err) + } + + if got != dir { + t.Fatalf("expected %q, got %q", dir, got) + } +} + +func TestUnloadDocumentStartsSearchWhenListingWasNotLoaded(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "index.md") + if err := os.WriteFile(path, []byte("# Test\n"), 0o600); err != nil { + t.Fatal(err) + } + + initSections() + common := &commonModel{ + cfg: Config{ + Path: path, + ShowAllFiles: true, + }, + } + m := model{ + common: common, + state: stateShowDocument, + stash: newStashModel(common), + pager: newPagerModel(common), + } + t.Cleanup(func() { + if err := m.pager.watcher.Close(); err != nil { + t.Fatal(err) + } + }) + + cmds := m.unloadDocument() + if len(cmds) == 0 { + t.Fatal("expected unload to start a local file search") + } + + var msg tea.Msg + for _, cmd := range cmds { + msg = cmd() + if _, ok := msg.(initLocalFileSearchMsg); ok { + break + } + } + + got, ok := msg.(initLocalFileSearchMsg) + if !ok { + t.Fatalf("expected initLocalFileSearchMsg, got %T", msg) + } + if got.cwd != dir { + t.Fatalf("expected search cwd %q, got %q", dir, got.cwd) + } + for range got.ch { + } +}