diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/client/ui/viminput/viminput.go | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/internal/client/ui/viminput/viminput.go b/internal/client/ui/viminput/viminput.go index 0008141..cefb5b6 100644 --- a/internal/client/ui/viminput/viminput.go +++ b/internal/client/ui/viminput/viminput.go @@ -873,7 +873,6 @@ func (m *Model) Motion(motion string) (line, col int) { return lnum, i } - // Search previous non-matching char if col < 0 || len(line) == 0 { return lnum, 0 @@ -974,7 +973,74 @@ func (m *Model) Motion(motion string) (line, col int) { return lnum, i } case "ge": - return Unchanged, m.cursorColumn - 1 + lnum := m.cursorLine + col := m.cursorColumn + remember := false + for { + line := m.lines[lnum] + isFirstLine := lnum == 0 + + // Skip if empty + if len(line) == 0 && !isFirstLine { + // What happens if this is the current line + if lnum == m.cursorLine { + lnum-- + col = len(m.lines[lnum]) - 1 + remember = true + continue + } + return lnum, 0 + } + + if remember { + i, ok := SearchCharFunc(line, col, -1, func(c rune) bool { + return !unicode.IsSpace(c) + }) + if !ok { + if isFirstLine { + return lnum, 0 + } + lnum-- + col = len(m.lines[lnum]) - 1 + continue + } + return lnum, i + } + + // 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, func(c rune) bool { + return unicode.IsSpace(c) || isWhitespace || isKeyword != IsKeyword(c) + }) + if !ok { + if isFirstLine { + return lnum, 0 + } + lnum-- + col = len(m.lines[lnum]) - 1 + remember = true + continue + } + + // Search start of next word + i, ok = SearchCharFunc(line, i, -1, func(c rune) bool { + return !unicode.IsSpace(c) + }) + if !ok { + if isFirstLine { + return lnum, 0 + } + lnum-- + col = len(m.lines[lnum]) - 1 + remember = true + continue + } + return lnum, i + } default: return Unchanged, Unchanged |
