func (t *Terminal) constrain() { count := t.merger.Length() height := t.maxItems() diffpos := t.cy - t.offset t.cy = util.Constrain(t.cy, 0, count-1) t.offset = util.Constrain(t.offset, t.cy-height+1, t.cy) // Adjustment if count-t.offset < height { t.offset = util.Max(0, count-height) t.cy = util.Constrain(t.offset+diffpos, 0, count-1) } t.offset = util.Max(0, t.offset) }
func (t *Terminal) maxItems() int { max := t.maxHeight() - 2 - len(t.header) if t.inlineInfo { max++ } return util.Max(max, 0) }
// Tokenize tokenizes the given string with the delimiter func Tokenize(runes []rune, delimiter Delimiter) []Token { if delimiter.str == nil && delimiter.regex == nil { // AWK-style (\S+\s*) tokens, prefixLength := awkTokenizer(runes) return withPrefixLengths(tokens, prefixLength) } var tokens []string if delimiter.str != nil { tokens = strings.Split(string(runes), *delimiter.str) for i := 0; i < len(tokens)-1; i++ { tokens[i] = tokens[i] + *delimiter.str } } else if delimiter.regex != nil { str := string(runes) for len(str) > 0 { loc := delimiter.regex.FindStringIndex(str) if loc == nil { loc = []int{0, len(str)} } last := util.Max(loc[1], 1) tokens = append(tokens, str[:last]) str = str[last:] } } asRunes := make([][]rune, len(tokens)) for i, token := range tokens { asRunes[i] = []rune(token) } return withPrefixLengths(asRunes, 0) }
// Transform is used to transform the input when --with-nth option is given func Transform(tokens []Token, withNth []Range) []Token { transTokens := make([]Token, len(withNth)) numTokens := len(tokens) for idx, r := range withNth { part := []rune{} minIdx := 0 if r.begin == r.end { idx := r.begin if idx == rangeEllipsis { part = append(part, joinTokensAsRunes(tokens)...) } else { if idx < 0 { idx += numTokens + 1 } if idx >= 1 && idx <= numTokens { minIdx = idx - 1 part = append(part, tokens[idx-1].text...) } } } else { var begin, end int if r.begin == rangeEllipsis { // ..N begin, end = 1, r.end if end < 0 { end += numTokens + 1 } } else if r.end == rangeEllipsis { // N.. begin, end = r.begin, numTokens if begin < 0 { begin += numTokens + 1 } } else { begin, end = r.begin, r.end if begin < 0 { begin += numTokens + 1 } if end < 0 { end += numTokens + 1 } } minIdx = util.Max(0, begin-1) for idx := begin; idx <= end; idx++ { if idx >= 1 && idx <= numTokens { part = append(part, tokens[idx-1].text...) } } } var prefixLength int if minIdx < numTokens { prefixLength = tokens[minIdx].prefixLength } else { prefixLength = 0 } transTokens[idx] = Token{part, prefixLength, util.TrimLen(part)} } return transTokens }
func (t *Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int, current bool) { var maxe int for _, offset := range item.offsets { maxe = util.Max(maxe, int(offset[1])) } // Overflow text := make([]rune, len(item.text)) copy(text, item.text) offsets := item.colorOffsets(col2, bold, current) maxWidth := C.MaxX() - 3 - t.marginInt[1] - t.marginInt[3] maxe = util.Constrain(maxe+util.Min(maxWidth/2-2, t.hscrollOff), 0, len(text)) fullWidth := displayWidth(text) if fullWidth > maxWidth { if t.hscroll { // Stri.. matchEndWidth := displayWidth(text[:maxe]) if matchEndWidth <= maxWidth-2 { text, _ = trimRight(text, maxWidth-2) text = append(text, []rune("..")...) } else { // Stri.. if matchEndWidth < fullWidth-2 { text = append(text[:maxe], []rune("..")...) } // ..ri.. var diff int32 text, diff = trimLeft(text, maxWidth-2) // Transform offsets for idx, offset := range offsets { b, e := offset.offset[0], offset.offset[1] b += 2 - diff e += 2 - diff b = util.Max32(b, 2) offsets[idx].offset[0] = b offsets[idx].offset[1] = util.Max32(b, e) } text = append([]rune(".."), text...) } } else { text, _ = trimRight(text, maxWidth-2) text = append(text, []rune("..")...) for idx, offset := range offsets { offsets[idx].offset[0] = util.Min32(offset.offset[0], int32(maxWidth-2)) offsets[idx].offset[1] = util.Min32(offset.offset[1], int32(maxWidth)) } } } var index int32 var substr string var prefixWidth int maxOffset := int32(len(text)) for _, offset := range offsets { b := util.Constrain32(offset.offset[0], index, maxOffset) e := util.Constrain32(offset.offset[1], index, maxOffset) substr, prefixWidth = processTabs(text[index:b], prefixWidth) C.CPrint(col1, bold, substr) if b < e { substr, prefixWidth = processTabs(text[b:e], prefixWidth) C.CPrint(offset.color, offset.bold, substr) } index = e if index >= maxOffset { break } } if index < maxOffset { substr, _ = processTabs(text[index:], prefixWidth) C.CPrint(col1, bold, substr) } }