-// SelectWord selects the word the cursor is currently on
-func (c *Cursor) SelectWord() {
- if len(c.buf.Line(c.Y)) == 0 {
- return
- }
-
- if !IsWordChar(string(c.RuneUnder(c.X))) {
- c.SetSelectionStart(c.Loc)
- c.SetSelectionEnd(c.Loc.Move(1, c.buf))
- c.OrigSelection = c.CurSelection
- return
- }
-
- forward, backward := c.X, c.X
-
- for backward > 0 && IsWordChar(string(c.RuneUnder(backward-1))) {
- backward--
- }
-
- c.SetSelectionStart(Loc{backward, c.Y})
- c.OrigSelection[0] = c.CurSelection[0]
-
- for forward < Count(c.buf.Line(c.Y))-1 && IsWordChar(string(c.RuneUnder(forward+1))) {
- forward++
- }
-
- c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.buf))
- c.OrigSelection[1] = c.CurSelection[1]
- c.Loc = c.CurSelection[1]
-}
-
-// AddWordToSelection adds the word the cursor is currently on to the selection
-func (c *Cursor) AddWordToSelection() {
- if c.Loc.GreaterThan(c.OrigSelection[0]) && c.Loc.LessThan(c.OrigSelection[1]) {
- c.CurSelection = c.OrigSelection
- return
- }
-
- if c.Loc.LessThan(c.OrigSelection[0]) {
- backward := c.X
-
- for backward > 0 && IsWordChar(string(c.RuneUnder(backward-1))) {
- backward--
- }
-
- c.SetSelectionStart(Loc{backward, c.Y})
- c.SetSelectionEnd(c.OrigSelection[1])
- }
-
- if c.Loc.GreaterThan(c.OrigSelection[1]) {
- forward := c.X
-
- for forward < Count(c.buf.Line(c.Y))-1 && IsWordChar(string(c.RuneUnder(forward+1))) {
- forward++
- }
-
- c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.buf))
- c.SetSelectionStart(c.OrigSelection[0])
- }
-
- c.Loc = c.CurSelection[1]
-}
-
-// SelectTo selects from the current cursor location to the given location
-func (c *Cursor) SelectTo(loc Loc) {
- if loc.GreaterThan(c.OrigSelection[0]) {
- c.SetSelectionStart(c.OrigSelection[0])
- c.SetSelectionEnd(loc)
- } else {
- c.SetSelectionStart(loc)
- c.SetSelectionEnd(c.OrigSelection[0])
- }
-}
-
-// WordRight moves the cursor one word to the right
-func (c *Cursor) WordRight() {
- for IsWhitespace(c.RuneUnder(c.X)) {
- if c.X == Count(c.buf.Line(c.Y)) {
- c.Right()
- return
- }
- c.Right()
- }
- c.Right()
- for IsWordChar(string(c.RuneUnder(c.X))) {
- if c.X == Count(c.buf.Line(c.Y)) {
- return
- }
- c.Right()
- }
-}
-
-// WordLeft moves the cursor one word to the left
-func (c *Cursor) WordLeft() {
- c.Left()
- for IsWhitespace(c.RuneUnder(c.X)) {
- if c.X == 0 {
- return
- }
- c.Left()
- }
- c.Left()
- for IsWordChar(string(c.RuneUnder(c.X))) {
- if c.X == 0 {
- return
- }
- c.Left()
- }
- c.Right()
-}
-
-// RuneUnder returns the rune under the given x position
-func (c *Cursor) RuneUnder(x int) rune {
- line := []rune(c.buf.Line(c.Y))
- if len(line) == 0 {
- return '\n'
- }
- if x >= len(line) {
- return '\n'
- } else if x < 0 {
- x = 0
- }
- return line[x]
-}
-