forked from oligo/gvcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathword.go
66 lines (59 loc) · 1.92 KB
/
word.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package gvcode
import (
"strings"
"unicode"
)
const (
// defaultWordSeperators defines a default set of word seperators. It is
// used when no custom word seperators are set.
defaultWordSeperators = "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?"
)
// isWordSeperator check r to see if it is a word seperator. A word seperator
// set the boundary when navigating by words, or deleting by words.
// TODO: does it make sence to use unicode space definition here?
func (e *textView) isWordSeperator(r rune) bool {
seperators := e.WordSeperators
if e.WordSeperators == "" {
seperators = defaultWordSeperators
}
return strings.ContainsRune(seperators, r) || unicode.IsSpace(r)
}
// MoveWord moves the caret to the next few words in the specified direction.
// Positive is forward, negative is backward.
// The final caret position will be aligned to a grapheme cluster boundary.
func (e *textView) MoveWords(distance int, selAct selectionAction) {
// split the distance information into constituent parts to be
// used independently.
words, direction := distance, 1
if distance < 0 {
words, direction = distance*-1, -1
}
// atEnd if caret is at either side of the buffer.
caret := e.closestToRune(e.caret.start)
atEnd := func() bool {
return caret.Runes == 0 || caret.Runes == e.Len()
}
// next returns the appropriate rune given the direction.
next := func() (r rune) {
if direction < 0 {
r, _ = e.src.ReadRuneAt(caret.Runes - 1)
} else {
r, _ = e.src.ReadRuneAt(caret.Runes)
}
return r
}
for ii := 0; ii < words; ii++ {
for r := next(); e.isWordSeperator(r) && !atEnd(); r = next() {
e.MoveCaret(direction, 0)
caret = e.closestToRune(e.caret.start)
}
e.MoveCaret(direction, 0)
caret = e.closestToRune(e.caret.start)
for r := next(); !e.isWordSeperator(r) && !atEnd(); r = next() {
e.MoveCaret(direction, 0)
caret = e.closestToRune(e.caret.start)
}
}
e.updateSelection(selAct)
e.clampCursorToGraphemes()
}