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 }