github.com/xyproto/orbiton/v2@v2.65.12-0.20240516144430-e10a419274ec/insertrune.go (about)

     1  package main
     2  
     3  import (
     4  	"github.com/xyproto/vt100"
     5  )
     6  
     7  // InsertRune will insert a rune at the current data position, with word wrap
     8  // Returns true if the line was wrapped
     9  func (e *Editor) InsertRune(c *vt100.Canvas, r rune) bool {
    10  	// Insert a regular space instead of a nonbreaking space.
    11  	// Nobody likes nonbreaking spaces.
    12  
    13  	if r == 0xc2a0 { // non-breaking space
    14  		r = ' '
    15  	} else if r == 0xcc88 { // annoying tilde
    16  		r = '~'
    17  	} else if r == 0xcdbe { // greek question mark
    18  		r = ';'
    19  	}
    20  
    21  	// The document will be changed
    22  	e.changed = true
    23  
    24  	// Repaint afterwards
    25  	e.redrawCursor = true
    26  	e.redraw = true
    27  
    28  	// Wrap a bit before the limit if the inserted rune is a space?
    29  	limit := e.wrapWidth
    30  	if r == ' ' {
    31  		// This is how long a word can be before being broken,
    32  		// and it "eats from" the right margin, so it needs to be balanced.
    33  		// TODO: Use an established method of word wrapping / breaking lines.
    34  		limit -= 5
    35  	}
    36  
    37  	// If wrapWhenTyping is enabled, check if we should wrap to the next line
    38  	if e.wrapWhenTyping && e.wrapWidth > 0 && e.pos.sx >= limit {
    39  
    40  		e.InsertLineBelow()
    41  		e.pos.sy++
    42  		y := e.pos.sy
    43  		e.Home()
    44  		e.pos.sx = 0
    45  		if r != ' ' {
    46  			e.Insert(r)
    47  			e.pos.sx = 1
    48  		}
    49  		e.pos.sy = y
    50  
    51  		h := 80
    52  		if c != nil {
    53  			h = int(c.Height())
    54  		}
    55  		if e.pos.sy >= (h - 1) {
    56  			e.ScrollDown(c, nil, 1)
    57  		}
    58  
    59  		e.Center(c)
    60  		e.redraw = true
    61  		e.redrawCursor = true
    62  
    63  		return true
    64  	}
    65  
    66  	// A regular insert, no wrapping
    67  	e.Insert(r)
    68  
    69  	// Scroll right when reaching 95% of the terminal width
    70  	wf := 80.0
    71  	if c != nil {
    72  		wf = float64(c.Width())
    73  	}
    74  	if e.pos.sx > int(wf*0.95) {
    75  		// scroll
    76  		e.pos.offsetX++
    77  		e.pos.sx--
    78  	}
    79  	return false
    80  }