code: func iterateString(text string, callback func(main rune, comb []rune, textPos, textWidth, screenPos, screenWidth int) bool) bool {
  	var screenPos int
  
  	gr := uniseg.NewGraphemes(text)
  	for gr.Next() {
  		r := gr.Runes()
  		from, to := gr.Positions()
  		width := stringWidth(gr.Str())
  		var comb []rune
  		if len(r) > 1 {
  			comb = r[1:]
  		}
  
  		//		panic(fmt.Sprintf(`from=%d to=%d screenPos=%d width=%d`, from, to, screenPos, width))
  		if callback(r[0], comb, from, to-from, screenPos, width) {
  			return true
  		}
  
  		screenPos += width
  	}
  
  	return false
  }
docs: // iterateString iterates through the given string one printed character at a
  // time. For each such character, the callback function is called with the
  // Unicode code points of the character (the first rune and any combining runes
  // which may be nil if there aren't any), the starting position (in bytes)
  // within the original string, its length in bytes, the screen position of the
  // character, and the screen width of it. The iteration stops if the callback
  // returns true. This function returns true if the iteration was stopped before
  // the last character.