github.com/jmigpin/editor@v1.6.0/util/iout/iorw/rwedit/tab.go (about) 1 package rwedit 2 3 import ( 4 "bytes" 5 6 "github.com/jmigpin/editor/util/iout/iorw" 7 ) 8 9 func TabRight(ctx *Ctx) error { 10 if !ctx.C.HaveSelection() { 11 return InsertString(ctx, "\t") 12 } 13 14 a, b, newline, err := ctx.CursorSelectionLinesIndexes() 15 if err != nil { 16 return err 17 } 18 19 // insert at lines start 20 for i := a; i < b; { 21 if err := ctx.RW.OverwriteAt(i, 0, []byte{'\t'}); err != nil { 22 return err 23 } 24 b += 1 // size of \t 25 26 rd := ctx.LocalReader(i) 27 u, _, err := iorw.LineEndIndex(rd, i) 28 if err != nil { 29 return err 30 } 31 i = u 32 } 33 34 // cursor index without the newline 35 if newline { 36 b-- 37 } 38 39 ctx.C.SetSelection(a, b) 40 return nil 41 } 42 43 func TabLeft(ctx *Ctx) error { 44 a, b, newline, err := ctx.CursorSelectionLinesIndexes() 45 if err != nil { 46 return err 47 } 48 49 // remove from lines start 50 altered := false 51 for i := a; i < b; { 52 s, err := ctx.RW.ReadFastAt(i, 1) 53 if err != nil { 54 return err 55 } 56 if bytes.ContainsAny(s, "\t ") { 57 altered = true 58 if err := ctx.RW.OverwriteAt(i, 1, nil); err != nil { 59 return err 60 } 61 b -= 1 // 1 is length of '\t' or ' ' 62 } 63 64 rd := ctx.LocalReader(i) 65 u, _, err := iorw.LineEndIndex(rd, i) 66 if err != nil { 67 return err 68 } 69 i = u 70 } 71 72 // skip making the selection 73 if !altered { 74 return nil 75 } 76 77 // cursor index without the newline 78 if newline { 79 b-- 80 } 81 82 ctx.C.SetSelection(a, b) 83 return nil 84 }