diff options
| author | Kyren223 <Kyren223@proton.me> | 2024-12-13 18:25:22 +0200 |
|---|---|---|
| committer | Kyren223 <Kyren223@proton.me> | 2024-12-13 18:25:22 +0200 |
| commit | ccb7fca556de6af410fe1342b5b43aa04e927cb0 (patch) | |
| tree | fbace71654e0ed965c24510ffd314ff282026b07 /internal/client | |
| parent | 29d70f27c508206da27b500ad9b11242bea31acc (diff) | |
Implemented e and b in viminput
Diffstat (limited to 'internal/client')
| -rw-r--r-- | internal/client/ui/viminput/viminput.go | 139 |
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 |
