summaryrefslogtreecommitdiff
path: root/internal/client
diff options
context:
space:
mode:
authorKyren223 <Kyren223@proton.me>2024-12-13 18:25:22 +0200
committerKyren223 <Kyren223@proton.me>2024-12-13 18:25:22 +0200
commitccb7fca556de6af410fe1342b5b43aa04e927cb0 (patch)
treefbace71654e0ed965c24510ffd314ff282026b07 /internal/client
parent29d70f27c508206da27b500ad9b11242bea31acc (diff)
Implemented e and b in viminput
Diffstat (limited to 'internal/client')
-rw-r--r--internal/client/ui/viminput/viminput.go139
1 files changed, 139 insertions, 0 deletions
diff --git a/internal/client/ui/viminput/viminput.go b/internal/client/ui/viminput/viminput.go
index 8a5d96c..f860efd 100644
--- a/internal/client/ui/viminput/viminput.go
+++ b/internal/client/ui/viminput/viminput.go
@@ -577,6 +577,77 @@ func (m *Model) Motion(motion string) (line, col int) {
}
return lnum, i - 1
}
+ case "e":
+ lnum := m.cursorLine
+ col := m.cursorColumn
+ for {
+ line := m.lines[lnum]
+ isLastLine := lnum == len(m.lines)-1
+ isColAtEnd := col == len(line)-1
+
+ // Skip if empty
+ if len(line) == 0 && !isLastLine {
+ lnum++
+ col = 0
+ continue
+ }
+
+ // Search next non-matching char
+ if len(line) == 0 {
+ return lnum, 0
+ }
+ if col >= len(line) {
+ return lnum, len(line) - 1
+ }
+ isKeyword := IsKeyword(line[col])
+ isWhitespace := unicode.IsSpace(line[col])
+ i, ok := SearchCharFunc(line, col+1, 1, func(c rune) bool {
+ return unicode.IsSpace(c) || isWhitespace || isKeyword != IsKeyword(c)
+ })
+ if !ok {
+ if isLastLine || !isColAtEnd {
+ return lnum, len(line) - 1
+ }
+ lnum++
+ col = 0
+ continue
+ }
+
+ // Found next word - Simple case
+ if i-1 != col {
+ return lnum, i - 1
+ }
+
+ // Search start of next word
+ i, ok = SearchCharFunc(line, col+1, 1, func(c rune) bool {
+ return !unicode.IsSpace(c)
+ })
+ if !ok {
+ if isLastLine {
+ return lnum, len(line) - 1
+ }
+ lnum++
+ col = 0
+ continue
+ }
+
+ // Next word exists, find it's end
+ isKeyword = IsKeyword(line[i])
+ isWhitespace = unicode.IsSpace(line[i])
+ i, ok = SearchCharFunc(line, i, 1, func(c rune) bool {
+ return unicode.IsSpace(c) || isWhitespace || isKeyword != IsKeyword(c)
+ })
+ if !ok {
+ if isLastLine || !isColAtEnd {
+ return lnum, len(line) - 1
+ }
+ // If at the end, continue to next line (if it exists)
+ lnum++
+ col = 0
+ continue
+ }
+ return lnum, i - 1
+ }
case "B":
lnum := m.cursorLine
col := m.cursorColumn
@@ -634,6 +705,74 @@ func (m *Model) Motion(motion string) (line, col int) {
}
return lnum, i + 1
}
+ case "b":
+ lnum := m.cursorLine
+ col := m.cursorColumn
+ for {
+ line := m.lines[lnum]
+ isFirstLine := lnum == 0
+ isColAtStart := col == 0
+
+ // Skip if empty
+ if len(line) == 0 && !isFirstLine {
+ lnum--
+ col = len(m.lines[lnum]) - 1
+ continue
+ }
+
+ // Search previous non-matching char
+ if col < 0 || len(line) == 0 {
+ return lnum, 0
+ }
+ isKeyword := IsKeyword(line[col])
+ isWhitespace := unicode.IsSpace(line[col])
+ i, ok := SearchCharFunc(line, col-1, -1, func(c rune) bool {
+ return unicode.IsSpace(c) || isWhitespace || isKeyword != IsKeyword(c)
+ })
+ if !ok {
+ if isFirstLine || !isColAtStart {
+ return lnum, 0
+ }
+ lnum--
+ col = len(m.lines[lnum]) - 1
+ continue
+ }
+
+ // Found next word - Simple case
+ if i+1 != col {
+ return lnum, i + 1
+ }
+
+ // Search end of previous word
+ i, ok = SearchCharFunc(line, col-1, -1, func(c rune) bool {
+ return !unicode.IsSpace(c)
+ })
+ if !ok {
+ if isFirstLine {
+ return lnum, 0
+ }
+ lnum--
+ col = len(m.lines[lnum]) - 1
+ continue
+ }
+
+ // Previous word exists, find it's start
+ isKeyword = IsKeyword(line[i])
+ isWhitespace = unicode.IsSpace(line[i])
+ i, ok = SearchCharFunc(line, i, -1, func(c rune) bool {
+ return unicode.IsSpace(c) || isWhitespace || isKeyword != IsKeyword(c)
+ })
+ if !ok {
+ if isFirstLine || !isColAtStart {
+ return lnum, 0
+ }
+ // If at the start, continue to previous line (if it exists)
+ lnum--
+ col = len(m.lines[lnum]) - 1
+ continue
+ }
+ return lnum, i + 1
+ }
default:
return Unchanged, Unchanged