// Generates a slice of rows with all of the data required for display. func (navigator *Navigator) View(maxRows int) *view.Buffer { var start, end, size int var entrySize string // Return the current directory path as the status. status := [2]string{navigator.CurrentPath(), ""} // Append a percentage to the status line, if // we're still calculating directory sizes. if navigator.pendingCalculations > 0 { entryCount := len(navigator.entries) status[1] = fmt.Sprintf("(%d%%)", (entryCount-navigator.pendingCalculations)*100/entryCount) } else { avail := int64(navigator.availableBytes()) total := int64(navigator.totalBytes()) status[1] = fmt.Sprintf("%v available (%v%% used)", view.Size(avail), (total-avail)*100/total) } // Create a slice with a size that is the lesser of the entry count and maxRows. entryCount := len(navigator.Entries()) if maxRows > entryCount { size = entryCount } else { size = maxRows } viewData := make([]view.Row, size, size) // Don't bother going any further if there are no entries to work with. if size == 0 { return &view.Buffer{Rows: viewData, Status: status} } // Deleting an entry can result in the cached view range indices // being out of bounds; correct that if it has occurred. if navigator.viewDataIndices[1] > entryCount { navigator.viewDataIndices[1] = entryCount } // Determine the range of entries to return. if navigator.viewDataIndices[1] != 0 && navigator.viewDataIndices[0] <= navigator.SelectedIndex() && navigator.SelectedIndex() < navigator.viewDataIndices[1] { // The selected entry is still visible in the slice last returned. Return // the same range of entries to keep the view as consistent as possible. start, end = navigator.viewDataIndices[0], navigator.viewDataIndices[1] } else if navigator.viewDataIndices[1] != 0 && navigator.SelectedIndex() < navigator.viewDataIndices[0] { // The selected entry is beneath the range of entries previously returned. // Shift the range down just enough to include the selected entry. start = navigator.SelectedIndex() end = navigator.SelectedIndex() + size } else if navigator.SelectedIndex() >= size { // The selected entry is either above the previously returned range, or // this function hasn't been called for the current directory yet. Either way, // it would be outside of the returned range if we started at zero, so return // a range with it at the top. start = navigator.SelectedIndex() + 1 - size end = navigator.SelectedIndex() + 1 } else { // Use the range starting at index 0. start = 0 end = size } // Copy the navigator entries' names and // formatted sizes into the slice we'll return. for i, entry := range navigator.Entries()[start:end] { highlight := i+int(start) == int(navigator.SelectedIndex()) // Add a trailing slash to the name // if the entry is a directory. var name string if entry.IsDirectory { name = entry.Name + "/" } else { name = entry.Name } if entry.SizeCalculated { entrySize = view.Size(entry.Size) } else { entrySize = "Calculating..." } viewData[i] = view.Row{name, entrySize, highlight, entry.IsDirectory} } // Store the indices used to generate the view data. navigator.viewDataIndices = [2]int{start, end} return &view.Buffer{Rows: viewData, Status: status} }
Describe("Status Line", func() { Context("when all calculations have completed", func() { BeforeEach(func() { // FIXME: This calculation gets stuck at 75%. // Hijack the navigator to simulate calculation completion. navigator.pendingCalculations = 0 }) It("returns the current directory path as its first element", func() { Expect(buffer.Status[0]).To(Equal(navigator.CurrentPath())) }) It("returns disk/partition space statistics as its second element", func() { avail := int64(navigator.availableBytes()) total := int64(navigator.totalBytes()) status := fmt.Sprintf("%v available (%v%% used)", view.Size(avail), (total-avail)*100/total) Expect(buffer.Status[1]).To(Equal(status)) }) }) }) Context("maxRows is set to 1", func() { BeforeEach(func() { maxRows = 1 }) It("returns a buffer with the right number of rows", func() { Expect(len(buffer.Rows)).To(BeEquivalentTo(maxRows)) }) It("stores the proper view data indices", func() {