github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/hint.go (about)

     1  package readline
     2  
     3  import "strings"
     4  
     5  func (rl *Instance) getHintText() {
     6  	if rl.HintText == nil {
     7  		rl.resetHintText()
     8  		return
     9  	}
    10  
    11  	hint := rl.cacheHint.Get(rl.line.Runes())
    12  	if len(hint) > 0 {
    13  		rl.hintText = hint
    14  		return
    15  	}
    16  
    17  	rl.hintText = rl.HintText(rl.line.Runes(), rl.line.RunePos())
    18  	rl.cacheHint.Append(rl.line.Runes(), rl.hintText)
    19  }
    20  
    21  func (rl *Instance) writeHintTextStr() string {
    22  	rl.tabMutex.Lock()
    23  	defer rl.tabMutex.Unlock()
    24  
    25  	if rl.HintText == nil {
    26  		rl.hintY = 0
    27  		return ""
    28  	}
    29  
    30  	if len(rl.hintText) == 0 {
    31  		rl.hintText = []rune{' '}
    32  	}
    33  
    34  	hintText := string(rl.hintText)
    35  
    36  	if rl.modeTabCompletion && rl.tcDisplayType == TabDisplayGrid &&
    37  		!rl.modeTabFind && len(rl.tcSuggestions) > 0 {
    38  		cell := (rl.tcMaxX * (rl.tcPosY - 1)) + rl.tcOffset + rl.tcPosX - 1
    39  		description := rl.tcDescriptions[rl.tcSuggestions[cell]]
    40  
    41  		if description != "" {
    42  			hintText = description
    43  		}
    44  	}
    45  
    46  	// fix bug https://github.com/lmorg/murex/issues/376
    47  	if rl.termWidth == 0 {
    48  		rl.termWidth = GetTermWidth()
    49  	}
    50  
    51  	// Determine how many lines hintText spans over
    52  	// (Currently there is no support for carriage returns / new lines)
    53  	hintLength := strLen(hintText)
    54  	n := float64(hintLength) / float64(rl.termWidth)
    55  	if float64(int(n)) != n {
    56  		n++
    57  	}
    58  	rl.hintY = int(n)
    59  
    60  	if rl.hintY > 3 {
    61  		rl.hintY = 3
    62  		hintText = hintText[:(rl.termWidth*3)-2] + "…"
    63  	} else {
    64  		padding := (rl.hintY * rl.termWidth) - len(hintText)
    65  		if padding < 0 {
    66  			padding = 0
    67  		}
    68  		hintText += strings.Repeat(" ", padding)
    69  	}
    70  
    71  	_, lineY := rl.lineWrapCellLen()
    72  	posX, posY := rl.lineWrapCellPos()
    73  	y := lineY - posY
    74  	write := moveCursorDownStr(y)
    75  
    76  	write += "\r\n" + rl.HintFormatting + hintText + seqReset
    77  
    78  	write += moveCursorUpStr(rl.hintY + lineY - posY)
    79  	write += moveCursorBackwardsStr(rl.termWidth)
    80  	write += moveCursorForwardsStr(posX)
    81  
    82  	return write
    83  }
    84  
    85  func (rl *Instance) resetHintText() {
    86  	rl.hintY = 0
    87  	rl.hintText = []rune{}
    88  }
    89  
    90  // ForceHintTextUpdate is a nasty function for force writing a new hint text. Use sparingly!
    91  func (rl *Instance) ForceHintTextUpdate(s string) {
    92  	rl.hintText = []rune(s)
    93  	print(rl.writeHintTextStr())
    94  }