mirror of
				https://github.com/sammy-ette/Hilbish
				synced 2025-08-10 02:52:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			141 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package readline
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"strconv"
 | 
						|
)
 | 
						|
 | 
						|
// initMap - Map display details. Called each time we want to be sure to have
 | 
						|
// a working completion group either immediately, or later on. Generally defered.
 | 
						|
func (g *CompletionGroup) initMap(rl *Instance) {
 | 
						|
 | 
						|
	// We make the map anyway, especially if we need to use it later
 | 
						|
	if g.Descriptions == nil {
 | 
						|
		g.Descriptions = make(map[string]string)
 | 
						|
	}
 | 
						|
 | 
						|
	// Compute size of each completion item box. Group independent
 | 
						|
	g.tcMaxLength = 1
 | 
						|
	for i := range g.Suggestions {
 | 
						|
		if len(g.Descriptions[g.Suggestions[i]]) > g.tcMaxLength {
 | 
						|
			g.tcMaxLength = len(g.Descriptions[g.Suggestions[i]])
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	g.tcPosX = 0
 | 
						|
	g.tcPosY = 0
 | 
						|
	g.tcOffset = 0
 | 
						|
 | 
						|
	// Number of lines allowed to be printed for group
 | 
						|
	if len(g.Suggestions) > g.MaxLength {
 | 
						|
		g.tcMaxY = g.MaxLength
 | 
						|
	} else {
 | 
						|
		g.tcMaxY = len(g.Suggestions)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// moveTabMapHighlight - Moves the highlighting for currently selected completion item (map display)
 | 
						|
func (g *CompletionGroup) moveTabMapHighlight(rl *Instance, x, y int) (done bool, next bool) {
 | 
						|
 | 
						|
	g.tcPosY += x
 | 
						|
	g.tcPosY += y
 | 
						|
 | 
						|
	// Lines
 | 
						|
	if g.tcPosY < 1 {
 | 
						|
		if rl.tabCompletionReverse {
 | 
						|
			if g.tcOffset > 0 {
 | 
						|
				g.tcPosY = 1
 | 
						|
				g.tcOffset--
 | 
						|
			} else {
 | 
						|
				return true, false
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if g.tcPosY > g.tcMaxY {
 | 
						|
		g.tcPosY--
 | 
						|
		g.tcOffset++
 | 
						|
	}
 | 
						|
 | 
						|
	if g.tcOffset+g.tcPosY < 1 && len(g.Suggestions) > 0 {
 | 
						|
		g.tcPosY = g.tcMaxY
 | 
						|
		g.tcOffset = len(g.Suggestions) - g.tcMaxY
 | 
						|
	}
 | 
						|
	if g.tcOffset < 0 {
 | 
						|
		g.tcOffset = 0
 | 
						|
	}
 | 
						|
 | 
						|
	if g.tcOffset+g.tcPosY > len(g.Suggestions) {
 | 
						|
		g.tcOffset--
 | 
						|
		return true, true
 | 
						|
	}
 | 
						|
	return false, false
 | 
						|
}
 | 
						|
 | 
						|
// writeMap - A map or list completion string
 | 
						|
func (g *CompletionGroup) writeMap(rl *Instance) (comp string) {
 | 
						|
 | 
						|
	if g.Name != "" {
 | 
						|
		// Print group title (changes with line returns depending on type)
 | 
						|
		comp += fmt.Sprintf("%s%s%s %s\n", BOLD, YELLOW, fmtEscape(g.Name), RESET)
 | 
						|
		rl.tcUsedY++
 | 
						|
	}
 | 
						|
 | 
						|
	termWidth := GetTermWidth()
 | 
						|
	if termWidth < 20 {
 | 
						|
		// terminal too small. Probably better we do nothing instead of crash
 | 
						|
		// We are more conservative than lmorg, and push it to 20 instead of 10
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// Set all necessary dimensions
 | 
						|
	maxLength := g.tcMaxLength
 | 
						|
	if maxLength > termWidth-9 {
 | 
						|
		maxLength = termWidth - 9
 | 
						|
	}
 | 
						|
	maxDescWidth := termWidth - maxLength - 4
 | 
						|
 | 
						|
	cellWidth := strconv.Itoa(maxLength)
 | 
						|
	itemWidth := strconv.Itoa(maxDescWidth)
 | 
						|
	y := 0
 | 
						|
 | 
						|
	// Highlighting function
 | 
						|
	highlight := func(y int) string {
 | 
						|
		if y == g.tcPosY && g.isCurrent {
 | 
						|
			return seqInvert
 | 
						|
		}
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
 | 
						|
	// String formating
 | 
						|
	var item, description string
 | 
						|
	for i := g.tcOffset; i < len(g.Suggestions); i++ {
 | 
						|
		y++ // Consider new item
 | 
						|
		if y > g.tcMaxY {
 | 
						|
			break
 | 
						|
		}
 | 
						|
 | 
						|
		item = g.Suggestions[i]
 | 
						|
 | 
						|
		if len(item) > maxDescWidth {
 | 
						|
			item = item[:maxDescWidth-3] + "..."
 | 
						|
		}
 | 
						|
 | 
						|
		description = g.Descriptions[g.Suggestions[i]]
 | 
						|
		if len(description) > maxLength {
 | 
						|
			description = description[:maxLength-3] + "..."
 | 
						|
		}
 | 
						|
 | 
						|
		comp += fmt.Sprintf("\r%-"+cellWidth+"s %s %-"+itemWidth+"s %s\n",
 | 
						|
			description, highlight(y), fmtEscape(item), seqReset)
 | 
						|
	}
 | 
						|
 | 
						|
	// Add the equivalent of this group's size to final screen clearing
 | 
						|
	if len(g.Suggestions) > g.MaxLength {
 | 
						|
		rl.tcUsedY += g.MaxLength
 | 
						|
	} else {
 | 
						|
		rl.tcUsedY += len(g.Suggestions)
 | 
						|
	}
 | 
						|
 | 
						|
	return
 | 
						|
}
 |