~eliasnaur/gio-patches

feat(editor): skip words with ctrl key modifier v1 PROPOSED

: 1
 feat(editor): skip words with ctrl key modifier

 1 files changed, 50 insertions(+), 2 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/13926/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] feat(editor): skip words with ctrl key modifier Export this patch

From: Jack Mordaunt <jackmordaunt@gmail.com>

---
 widget/editor.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)

Adds word skip functionality common to text editors.
Holding down `ctrl+arrow` navigates the caret to the next/previous word.

diff --git a/widget/editor.go b/widget/editor.go
index 7e8fddb..8ab229d 100644
--- a/widget/editor.go
+++ b/widget/editor.go
@@ -9,6 +9,7 @@ import (
	"math"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"

	"gioui.org/f32"
@@ -278,9 +279,17 @@ func (e *Editor) command(k key.Event) bool {
	case key.NameDownArrow:
		e.moveLines(+1)
	case key.NameLeftArrow:
		e.Move(-1)
		if k.Modifiers.Contain(key.ModCtrl) {
			e.moveWord(-1)
		} else {
			e.Move(-1)
		}
	case key.NameRightArrow:
		e.Move(1)
		if k.Modifiers.Contain(key.ModCtrl) {
			e.moveWord(1)
		} else {
			e.Move(1)
		}
	case key.NamePageUp:
		e.movePages(-1)
	case key.NamePageDown:
@@ -775,6 +784,45 @@ func (e *Editor) moveEnd() {
	e.caret.xoff = l.Width + a - e.caret.x
}

// moveWord moves the caret to the next word in the specified direction.
// Positive is forward, negative is backword.
// Absolute values greater than one will skip that many words.
func (e *Editor) moveWord(distance int) {
	e.makeValid()
	var (
		// split the distance information into constituent parts to be
		// used independently.
		words, direction = func(n int) (int, int) {
			if n < 0 {
				return n * -1, -1
			} else {
				return n, 1
			}
		}(distance)
		// atEnd if caret is at either side of the buffer.
		atEnd = func() bool {
			return e.rr.caret == 0 || e.rr.caret == e.rr.len()
		}
		// next returns the appropriate rune given the direction.
		next = func() (r rune) {
			if direction < 0 {
				r, _ = e.rr.runeBefore(e.rr.caret)
			} else {
				r, _ = e.rr.runeAt(e.rr.caret)
			}
			return r
		}
	)
	for ii := 0; ii < words; ii++ {
		for {
			e.Move(direction)
			if r := next(); unicode.IsSpace(r) || atEnd() {
				break
			}
		}
	}
}

func (e *Editor) scrollToCaret() {
	e.makeValid()
	l := e.lines[e.caret.line]
-- 
2.28.0.windows.1
Thank you. Can you add a test along with the others in editor_test.go?

Elias