src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

edit.go (2009B)


      1 package buffer
      2 
      3 import (
      4 	"unicode"
      5 	"unicode/utf8"
      6 
      7 	"code.dwrz.net/src/pkg/editor/buffer/glyph"
      8 	"code.dwrz.net/src/pkg/editor/buffer/line"
      9 )
     10 
     11 func (b *Buffer) Backspace() {
     12 	var cl = b.CursorLine()
     13 
     14 	switch {
     15 	// Don't do anything at the beginning of the buffer.
     16 	case b.cursor.line == 0 && b.cursor.index == 0:
     17 
     18 	// Delete empty lines.
     19 	case cl.Length() == 0:
     20 		b.lines = append(
     21 			b.lines[:b.cursor.line],
     22 			b.lines[b.cursor.line+1:]...,
     23 		)
     24 
     25 		b.CursorUp()
     26 		b.CursorEnd()
     27 
     28 	// Append to the previous line.
     29 	case b.cursor.line != 0 && b.cursor.index == 0:
     30 		index := b.cursor.line
     31 
     32 		b.CursorUp()
     33 		b.CursorEnd()
     34 
     35 		b.lines[index-1].Append(cl.String())
     36 
     37 		b.lines = append(
     38 			b.lines[:index],
     39 			b.lines[index+1:]...,
     40 		)
     41 
     42 	// Delete a rune.
     43 	default:
     44 		b.CursorLeft()
     45 		b.CursorLine().DeleteRune(b.cursor.index)
     46 	}
     47 }
     48 
     49 func (b *Buffer) Insert(r rune) {
     50 	switch {
     51 	case r == '\n' || r == '\r':
     52 		b.Newline()
     53 
     54 	case r == '\t':
     55 		b.CursorLine().Insert(b.cursor.index, r)
     56 		b.cursor.index += utf8.RuneLen(r)
     57 		b.cursor.glyph += glyph.Width(r)
     58 
     59 	// Ignore all other non-printable characters.
     60 	case !unicode.IsPrint(r):
     61 		return
     62 
     63 	default:
     64 		b.CursorLine().Insert(b.cursor.index, r)
     65 		b.cursor.index += utf8.RuneLen(r)
     66 		b.cursor.glyph += glyph.Width(r)
     67 	}
     68 }
     69 
     70 // At the start of a line, create a new line above.
     71 // At the end of the line, create a new line below.
     72 // In the middle of a line, any remaining runes go to the next line.
     73 // TODO: using the cursor index will probably break with marks.
     74 func (b *Buffer) Newline() {
     75 	var cl = b.CursorLine()
     76 
     77 	switch {
     78 	case b.cursor.index == 0:
     79 		b.lines = append(
     80 			b.lines[:b.cursor.line+1],
     81 			b.lines[b.cursor.line:]...,
     82 		)
     83 		b.lines[b.cursor.line] = line.New("")
     84 
     85 	default:
     86 		text := cl.String()
     87 		rest := line.New(text[b.cursor.index:])
     88 
     89 		b.lines = append(
     90 			b.lines[:b.cursor.line+1],
     91 			b.lines[b.cursor.line:]...,
     92 		)
     93 		b.lines[b.cursor.line] = line.New(text[:b.cursor.index])
     94 		b.lines[b.cursor.line+1] = rest
     95 	}
     96 
     97 	b.CursorDown()
     98 	b.CursorHome()
     99 }