func (nc *navColumn) Show(i, w int) styled { s := nc.candidates[i] if w >= navigationListingMinWidthForPadding { return styled{" " + util.ForceWcwidth(s.text, w-2), s.style} } return styled{util.ForceWcwidth(s.text, w), s.style} }
func (hl *histlist) Show(i, width int) styled { entry := hl.shown[i] lines := strings.Split(entry, "\n") var b bytes.Buffer first := fmt.Sprintf("%*d %s", hl.indexWidth, hl.index[i], lines[0]) b.WriteString(util.ForceWcwidth(first, width)) indent := strings.Repeat(" ", hl.indexWidth+1) for _, line := range lines[1:] { b.WriteByte('\n') b.WriteString(util.ForceWcwidth(indent+line, width)) } return unstyled(b.String()) }
func (b *bang) Show(i, width int) styled { entry := b.filtered[i] var head string if entry.i == -1 { head = "M-, " } else if b.minus { head = fmt.Sprintf("%3d ", entry.i-len(b.words)) } else { head = fmt.Sprintf("%3d ", entry.i) } return unstyled(util.ForceWcwidth(head+entry.s, width)) }
func (comp *completion) List(width, maxHeight int) *buffer { b := newBuffer(width) cands := comp.candidates if len(cands) == 0 { b.writes(util.TrimWcwidth("(no result)", width), "") return b } if maxHeight <= 1 || width <= 2 { b.writes(util.TrimWcwidth("(terminal too small)", width), "") return b } // Reserve the leftmost row and the rightmost row as margins. width -= 2 // Determine comp.height and comp.firstShown. // First determine whether all candidates can be fit in the screen, // assuming that they are all of maximum width. If that is the case, we use // the computed height as the height for the listing, and the first // candidate to show is 0. Otherwise, we use min(height, len(cands)) as the // height and find the first candidate to show. perLine := max(1, width/(comp.maxWidth(0, len(cands))+completionColMarginTotal)) heightBound := util.CeilDiv(len(cands), perLine) first := 0 height := 0 if heightBound < maxHeight { height = heightBound } else { height = min(maxHeight, len(cands)) // Determine the first column to show. We start with the column in which the // selected one is found, moving to the left until either the width is // exhausted, or the old value of firstShown has been hit. first = comp.selected / height * height w := comp.maxWidth(first, first+height) + completionColMarginTotal for ; first > comp.firstShown; first -= height { dw := comp.maxWidth(first-height, first) + completionColMarginTotal if w+dw > width { break } w += dw } } comp.height = height comp.firstShown = first var i, j int remainedWidth := width trimmed := false // Show the results in columns, until width is exceeded. for i = first; i < len(cands); i += height { // Determine the width of the column (without the margin) colWidth := comp.maxWidth(i, min(i+height, len(cands))) totalColWidth := colWidth + completionColMarginTotal if totalColWidth > remainedWidth { totalColWidth = remainedWidth colWidth = totalColWidth - completionColMarginTotal trimmed = true } col := newBuffer(totalColWidth) for j = i; j < i+height; j++ { if j > i { col.newline() } if j >= len(cands) { // Write padding to make the listing a rectangle. col.writePadding(totalColWidth, styleForCompletion.String()) } else { col.writePadding(completionColMarginLeft, styleForCompletion.String()) s := joinStyles(styleForCompletion, cands[j].display.styles) if j == comp.selected { s = append(s, styleForSelectedCompletion.String()) } col.writes(util.ForceWcwidth(cands[j].display.text, colWidth), s.String()) col.writePadding(completionColMarginRight, styleForCompletion.String()) if !trimmed { comp.lastShownInFull = j } } } // Set w=1 for the leftmost margin. b.extendHorizontal(col, 1) remainedWidth -= totalColWidth if remainedWidth <= completionColMarginTotal { break } } // When the listing is incomplete, always use up the entire width. if remainedWidth > 0 && comp.needScrollbar() { col := newBuffer(remainedWidth) for i := 0; i < height; i++ { if i > 0 { col.newline() } col.writePadding(remainedWidth, styleForCompletion.String()) } b.extendHorizontal(col, 0) remainedWidth = 0 } return b }