From 7d9a1adb1ec79665dae74773fc5d18aa97893b6d Mon Sep 17 00:00:00 2001 From: Kyren223 Date: Mon, 3 Feb 2025 19:29:16 +0200 Subject: [PATCH] Added support for viw/vaw and viW/vaW in viminput --- internal/client/ui/viminput/viminput.go | 93 +++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/internal/client/ui/viminput/viminput.go b/internal/client/ui/viminput/viminput.go index f9c0319..ac322f6 100644 --- a/internal/client/ui/viminput/viminput.go +++ b/internal/client/ui/viminput/viminput.go @@ -1668,10 +1668,34 @@ func (m *Model) handleVisualModeKeys(key tea.KeyMsg) { m.SetCursorColumn(min(m.cursorColumn, len(m.lines[m.cursorLine])-1)) m.mode = NormalMode m.count = NoCount + + m.imod = false + m.amod = false return } motion := key.String() + + // Text objects + if motion == "i" && !m.imod { + m.imod = true + return + } else if m.imod { + m.imod = false + motion = "i" + motion + } else { + m.imod = false + } + if motion == "a" && !m.amod { + m.amod = true + return + } else if m.amod { + m.amod = false + motion = "a" + motion + } else { + m.amod = false + } + if motion == "o" { line, col := m.vline, m.vcol m.vline = m.cursorLine @@ -1681,6 +1705,69 @@ func (m *Model) handleVisualModeKeys(key tea.KeyMsg) { return } + if motion == "iW" || motion == "aW" { + line := m.lines[m.cursorLine] + if len(line) == 0 || m.cursorColumn == len(line) { + return + } + + isWhitespace := unicode.IsSpace(line[m.cursorColumn]) + lower := m.cursorColumn + upper := m.cursorColumn + 1 + searchFunc := func(c rune) bool { + return isWhitespace != unicode.IsSpace(c) + } + + i, ok := SearchCharFunc(line, lower, -1, searchFunc) + if ok { + lower = i + 1 + } else { + lower = 0 + } + + i, ok = SearchCharFunc(line, upper, 1, searchFunc) + if ok { + upper = i + } else { + upper = len(line) + } + + m.vcol = lower + m.SetCursorColumn(max(min(upper-1, len(line)-1), lower)) + } + + if motion == "iw" || motion == "aw" { + line := m.lines[m.cursorLine] + if len(line) == 0 || m.cursorColumn == len(line) { + return + } + + isKeyword := IsKeyword(line[m.cursorColumn]) + isWhitespace := unicode.IsSpace(line[m.cursorColumn]) + lower := m.cursorColumn + upper := m.cursorColumn + 1 + searchFunc := func(c rune) bool { + return isKeyword != IsKeyword(c) || isWhitespace != unicode.IsSpace(c) + } + + i, ok := SearchCharFunc(line, lower, -1, searchFunc) + if ok { + lower = i + 1 + } else { + lower = 0 + } + + i, ok = SearchCharFunc(line, upper, 1, searchFunc) + if ok { + upper = i + } else { + upper = len(line) + } + + m.vcol = lower + m.SetCursorColumn(max(min(upper-1, len(line)-1), lower)) + } + count := 1 if m.count != NoCount && (motion[0] < '0' || motion[0] > '9') { count = m.count @@ -1707,6 +1794,9 @@ func (m *Model) handleVisualModeKeys(key tea.KeyMsg) { m.SetCursorColumn(min(m.cursorColumn, len(m.lines[m.cursorLine])-1)) m.mode = VisualLineMode m.count = NoCount + + m.imod = false + m.amod = false return } @@ -1715,6 +1805,9 @@ func (m *Model) handleVisualModeKeys(key tea.KeyMsg) { return } + m.imod = false + m.amod = false + paste := "" if motion == "p" || motion == "P" { paste = m.Paste()