From d9cc7150e68636cfb4e74b15b5db1cc72d533c49 Mon Sep 17 00:00:00 2001 From: b4b4r07 Date: Wed, 16 Aug 2017 18:15:37 +0900 Subject: [PATCH] Imitate general ControlW behavior --- document.go | 27 +++++++++++++++++++++- document_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ emacs.go | 2 +- 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/document.go b/document.go index a98f9f6..94a410e 100644 --- a/document.go +++ b/document.go @@ -54,7 +54,14 @@ func (d *Document) GetWordBeforeCursor() string { return x[d.FindStartOfPreviousWord():] } -// FindStartOfPreviousWord return an index relative to the cursor position +// GetWordBeforeCursorWithSpace returns the word before the cursor. +// Unlike GetWordBeforeCursor, it returns string containing space +func (d *Document) GetWordBeforeCursorWithSpace() string { + x := d.TextBeforeCursor() + return x[d.FindStartOfPreviousWordWithSpace():] +} + +// FindStartOfPreviousWord returns an index relative to the cursor position // pointing to the start of the previous word. Return `None` if nothing was found. func (d *Document) FindStartOfPreviousWord() int { // Reverse the text before the cursor, in order to do an efficient backwards search. @@ -68,6 +75,24 @@ func (d *Document) FindStartOfPreviousWord() int { return 0 } +// FindStartOfPreviousWordWithSpace is almost the same as FindStartOfPreviousWord. +// The only difference is to ignore contiguous spaces. +func (d *Document) FindStartOfPreviousWordWithSpace() int { + // Reverse the text before the cursor, in order to do an efficient backwards search. + x := d.TextBeforeCursor() + l := len(x) + appear := false + for i := l; i > 0; i-- { + if x[i-1:i] != " " { + appear = true + } + if x[i-1:i] == " " && appear { + return i + } + } + return 0 +} + // CurrentLineBeforeCursor returns the text from the start of the line until the cursor. func (d *Document) CurrentLineBeforeCursor() string { s := strings.Split(d.TextBeforeCursor(), "\n") diff --git a/document_test.go b/document_test.go index 92ec82f..ca04716 100644 --- a/document_test.go +++ b/document_test.go @@ -88,6 +88,35 @@ func TestDocument_GetWordBeforeCursor(t *testing.T) { } } +func TestDocument_GetWordBeforeCursorWithSpace(t *testing.T) { + pattern := []struct { + document *Document + expected string + }{ + { + document: &Document{ + Text: "apple bana ", + CursorPosition: len("apple bana "), + }, + expected: "bana ", + }, + { + document: &Document{ + Text: "apple ", + CursorPosition: len("apple "), + }, + expected: "apple ", + }, + } + + for _, p := range pattern { + ac := p.document.GetWordBeforeCursorWithSpace() + if ac != p.expected { + t.Errorf("Should be %#v, got %#v", p.expected, ac) + } + } +} + func TestDocument_FindStartOfPreviousWord(t *testing.T) { pattern := []struct { document *Document @@ -117,6 +146,35 @@ func TestDocument_FindStartOfPreviousWord(t *testing.T) { } } +func TestDocument_FindStartOfPreviousWordWithSpace(t *testing.T) { + pattern := []struct { + document *Document + expected int + }{ + { + document: &Document{ + Text: "apple bana ", + CursorPosition: len("apple bana "), + }, + expected: len("apple "), + }, + { + document: &Document{ + Text: "apple ", + CursorPosition: len("apple "), + }, + expected: len(""), + }, + } + + for _, p := range pattern { + ac := p.document.FindStartOfPreviousWordWithSpace() + if ac != p.expected { + t.Errorf("Should be %#v, got %#v", p.expected, ac) + } + } +} + func TestDocument_CurrentLineBeforeCursor(t *testing.T) { d := &Document{ Text: "line 1\nline 2\nline 3\nline 4\n", diff --git a/emacs.go b/emacs.go index a18b6b0..9ac9b8a 100644 --- a/emacs.go +++ b/emacs.go @@ -103,7 +103,7 @@ var emacsKeyBindings = []KeyBind{ { Key: ControlW, Fn: func(buf *Buffer) { - buf.DeleteBeforeCursor(len([]rune(buf.Document().GetWordBeforeCursor()))) + buf.DeleteBeforeCursor(len([]rune(buf.Document().GetWordBeforeCursorWithSpace()))) }, }, }