Example #1
0
// 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}
}
Example #2
0
		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() {